Skip to content

Commit

Permalink
Fix for loops
Browse files Browse the repository at this point in the history
  • Loading branch information
benson1029 committed Apr 10, 2024
1 parent 1e31ab4 commit 51daf09
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/go/ece/microcode/for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { ControlFor } from '../../heap/types/control/for';
import { PrimitiveBool } from '../../heap/types/primitive/bool';
import { auto_cast } from '../../heap/types/auto_cast';
import { ControlForI } from '../../heap/types/control/for_i';
import { TAG_COMPLEX_string, TAG_CONTROL_exit_scope_i, TAG_CONTROL_for_i, TAG_CONTROL_var } from '../../heap/types/tags';
import { TAG_COMPLEX_string, TAG_CONTROL_exit_scope_i, TAG_CONTROL_for_i, TAG_CONTROL_marker_i, TAG_CONTROL_var } from '../../heap/types/tags';
import { ControlVar } from '../../heap/types/control/var';
import { ComplexString } from '../../heap/types/complex/string';

function evaluate_for(cmd: number, heap: Heap, C: ContextControl, S: ContextStash, E: ContextEnv): void {
const cmd_object = new ControlFor(heap, cmd);
Expand Down Expand Up @@ -67,9 +68,21 @@ function evaluate_for_i(cmd: number, heap: Heap, C: ContextControl, S: ContextSt
E.push_frame();
E.get_frame().insert_new_variable(loopVar.address);
E.get_frame().get_variable_address(loopVar.address).set_value(value);
const assign_i_cmd = heap.allocate_any({ tag: "assign_i" });
C.push(assign_i_cmd);
heap.free_object(assign_i_cmd);
const name_address_cmd = heap.allocate_any({ tag: "name-address", name: (loopVar as ComplexString).get_string() });
C.push(name_address_cmd);
heap.free_object(name_address_cmd);
const exit_scope_cmd = heap.allocate_any({ tag: "exit-scope_i" });
C.push(exit_scope_cmd);
heap.free_object(exit_scope_cmd);
const name_cmd = heap.allocate_any({ tag: "name", name: (loopVar as ComplexString).get_string() });
C.push(name_cmd);
heap.free_object(name_cmd);
const marker_cmd = heap.allocate_any({ tag: "marker_i" });
C.push(marker_cmd);
heap.free_object(marker_cmd);
}

C.push(body.address);
Expand All @@ -96,11 +109,8 @@ function evaluate_break(cmd: number, heap: Heap, C: ContextControl, S: ContextSt
function evaluate_continue(cmd: number, heap: Heap, C: ContextControl, S: ContextStash, E: ContextEnv): void {
const cmd_object = new ControlForI(heap, cmd);
const top_cmd = auto_cast(heap, C.pop());
if (top_cmd.get_tag() === TAG_CONTROL_for_i) {
const for_i_cmd = top_cmd as ControlForI;
C.push(for_i_cmd.address);
C.push(for_i_cmd.get_condition_address().address);
C.push(for_i_cmd.get_update_address().address);
if (top_cmd.get_tag() === TAG_CONTROL_marker_i) {
// Do nothing to finish the continuing
} else {
if (top_cmd.get_tag() === TAG_CONTROL_exit_scope_i) {
E.pop_frame();
Expand Down
1 change: 1 addition & 0 deletions src/go/ece/microcode/lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ function lookup_microcode_sequential(tag: number): Function {
return array.evaluate_slice_address;
case tags.TAG_CONTROL_slice_address_i:
return array.evaluate_slice_address_i;
case tags.TAG_CONTROL_marker_i:
case tags.TAG_PRIMITIVE_nil:
return (...args: any[]) => {};
default:
Expand Down
30 changes: 30 additions & 0 deletions src/go/ece/tests/control.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,34 @@ describe('Evaluating control structures', () => {
fmt.Println(f())
`)).toBe("2\n");
})

it('loop variable can be updated in loop scope', () => {
expect(evaluateSequence(`
var f func() int32
for i := 0; i < 10; i++ {
f = func() int32 {
return i
}
i++
fmt.Println(i)
}
fmt.Println(f())
`)).toBe("1\n3\n5\n7\n9\n9\n");
})

it('loop variable can be updated in loop scope (wt. continue)', () => {
expect(evaluateSequence(`
var f func() int32
for i := 0; i < 10; i++ {
f = func() int32 {
return i
}
i++
fmt.Println(i)
continue
fmt.Println("unreachable")
}
fmt.Println(f())
`)).toBe("1\n3\n5\n7\n9\n9\n");
})
})
12 changes: 12 additions & 0 deletions src/go/heap/heap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import { ControlLogicalI } from "./types/control/logical_i";
import { ControlLogicalImmI } from "./types/control/logical_imm_i";
import { ControlMake } from "./types/control/make";
import { ControlMakeI } from "./types/control/make_i";
import { ControlMarkerI } from "./types/control/marker_i";
import { ControlMember } from "./types/control/member";
import { ControlMemberAddress } from "./types/control/member_address";
import { ControlMemberAddressI } from "./types/control/member_address_i";
Expand Down Expand Up @@ -186,6 +187,7 @@ import {
TAGSTRING_CONTROL_slice_address,
TAGSTRING_CONTROL_slice_address_i,
TAGSTRING_USER_type_wait_group,
TAGSTRING_CONTROL_marker_i,
} from "./types/tags";
import { UserType } from "./types/user/type";
import { UserTypeArray } from "./types/user/type/array";
Expand Down Expand Up @@ -1176,6 +1178,14 @@ class Heap {
return ControlSliceAddressI.allocate(this);
}

/**
* CONTROL_marker_i
* Fields : none
*/
public allocate_CONTROL_marker_i(): number {
return ControlMarkerI.allocate(this);
}

/**
* ENVIRONMENT_frame
* Fields : number of children
Expand Down Expand Up @@ -1488,6 +1498,8 @@ class Heap {
return this.allocate_CONTROL_slice_address_i();
case TAGSTRING_CONTROL_push_i:
return this.allocate_CONTROL_push_i(obj);
case TAGSTRING_CONTROL_marker_i:
return this.allocate_CONTROL_marker_i();
case TAGSTRING_ENVIRONMENT_frame:
return this.allocate_ENVIRONMENT_frame(obj);
case TAGSTRING_USER_type_array:
Expand Down
4 changes: 4 additions & 0 deletions src/go/heap/types/auto_cast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { ControlLogicalI } from "./control/logical_i";
import { ControlLogicalImmI } from "./control/logical_imm_i";
import { ControlMake } from "./control/make";
import { ControlMakeI } from "./control/make_i";
import { ControlMarkerI } from "./control/marker_i";
import { ControlMember } from "./control/member";
import { ControlMemberAddress } from "./control/member_address";
import { ControlMemberAddressI } from "./control/member_address_i";
Expand Down Expand Up @@ -183,6 +184,7 @@ import {
TAG_CONTROL_slice_address_i,
TAG_COMPLEX_wait_group,
TAG_USER_type_wait_group,
TAG_CONTROL_marker_i,
} from "./tags"
import { UserChannel } from "./user/channel";
import { UserSlice } from "./user/slice";
Expand Down Expand Up @@ -352,6 +354,8 @@ function auto_cast(heap: Heap, address: number): HeapObject {
return new ControlSliceAddress(heap, address);
case TAG_CONTROL_slice_address_i:
return new ControlSliceAddressI(heap, address);
case TAG_CONTROL_marker_i:
return new ControlMarkerI(heap, address);
case TAG_ENVIRONMENT_entry:
return new EnvironmentEntry(heap, address);
case TAG_ENVIRONMENT_frame:
Expand Down
24 changes: 24 additions & 0 deletions src/go/heap/types/control/marker_i.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* CONTROL_marker_i
* Fields : None
*/

import { Heap } from "../../heap";
import { HeapObject } from "../objects";
import { TAG_CONTROL_marker_i } from "../tags";

class ControlMarkerI extends HeapObject {
public static allocate(heap: Heap): number {
return heap.allocate_object(TAG_CONTROL_marker_i, 0, 0);
}

public stringify_i(): string {
return this.address.toString() + " (marker_i)";
}

public to_object(): any {
return "MARKER_I";
}
}

export { ControlMarkerI };
2 changes: 2 additions & 0 deletions src/go/heap/types/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const TAG_CONTROL_chan_send_i = 0x8009; // 1000 0000 0000 1001
export const TAG_CONTROL_chan_receive_i = 0x800A; // 1000 0000 0000 1010
export const TAG_CONTROL_slice_i = 0x800B; // 1000 0000 0000 1011
export const TAG_CONTROL_slice_address_i = 0x800C; // 1000 0000 0000 1100
export const TAG_CONTROL_marker_i = 0x800D; // 1000 0000 0000 1101


export const TAG_CONTROL_name = 0xC001; // 1100 0000 0000 0001
Expand Down Expand Up @@ -197,6 +198,7 @@ export const TAGSTRING_CONTROL_member_address_i = "member_address_i";
export const TAGSTRING_CONTROL_push_i = "push_i";
export const TAGSTRING_CONTROL_slice_i = "slice_i";
export const TAGSTRING_CONTROL_slice_address_i = "slice_address_i";
export const TAGSTRING_CONTROL_marker_i = "marker_i";


export const TAGSTRING_USER_type_bool = "bool-type";
Expand Down

0 comments on commit 51daf09

Please sign in to comment.