Skip to content
This repository was archived by the owner on Oct 3, 2021. It is now read-only.

Commit 2796eec

Browse files
authored
Merge pull request #1 from looplanguage/feat_scoped_variables
feat: scoped variables
2 parents 9ea9aad + ae1e0f4 commit 2796eec

7 files changed

Lines changed: 56 additions & 30 deletions

File tree

.github/workflows/test.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
on: [push, pull_request]
2+
name: Test
3+
jobs:
4+
test:
5+
strategy:
6+
matrix:
7+
go-version: [1.17.x]
8+
os: [ubuntu-latest, macos-latest, windows-latest]
9+
runs-on: ${{ matrix.os }}
10+
steps:
11+
- name: Install Go
12+
uses: actions/setup-go@v2
13+
with:
14+
go-version: ${{ matrix.go-version }}
15+
- name: Checkout code
16+
uses: actions/checkout@v2
17+
- name: Test
18+
run: go test ./...

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ module github.com/looplanguage/lpvm
33
go 1.17
44

55
require (
6-
github.com/looplanguage/compiler v0.2.0
7-
github.com/looplanguage/loop v0.5.1
6+
github.com/looplanguage/compiler v0.3.0
7+
github.com/looplanguage/loop v0.5.2
88
)

go.sum

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,4 @@
1-
github.com/looplanguage/compiler v0.2.0 h1:W5jCgYdAVWtrPxmtwGIVqY2Qcz8kObTi9Fu0dQb0HIg=
2-
github.com/looplanguage/compiler v0.2.0/go.mod h1:D7uS6iANNHNNakYcMlrj1xw7TuBcoqImJOhLiprjRXc=
3-
github.com/looplanguage/loop v0.2.1 h1:nsNSOdpudJDflBpv/E1Fg7chBZ4XwTG13hwEqKNccGE=
4-
github.com/looplanguage/loop v0.2.1/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
5-
github.com/looplanguage/loop v0.2.2 h1:ZONRZv4NllPURvJd1BdOLy+KZjWaoaEZDHVvdXXFgyo=
6-
github.com/looplanguage/loop v0.2.2/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
7-
github.com/looplanguage/loop v0.3.0 h1:8F/XJol3pCq6ZWos0ApliAY7HTRLD23Cu9qUJP9wgng=
8-
github.com/looplanguage/loop v0.3.0/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
9-
github.com/looplanguage/loop v0.3.1 h1:F6UKew6tc/+Ebd3OX6nIKUGUt8IXT4ZtymSPa3WADDA=
10-
github.com/looplanguage/loop v0.3.1/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
11-
github.com/looplanguage/loop v0.3.2 h1:GeAPoMkUCNgUS0nfcEYKPcEwdSay+l5Sayhe0o72gc8=
12-
github.com/looplanguage/loop v0.3.2/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
13-
github.com/looplanguage/loop v0.4.0 h1:HTa0CLCtaNo8ErSB43yIgzMTmgwKJiw1ckQDrb2ljG0=
14-
github.com/looplanguage/loop v0.4.0/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
15-
github.com/looplanguage/loop v0.5.0 h1:Tyz24iVPmZExN8SIhcXUWSFFHENsLeyR9JcpvzkpZag=
16-
github.com/looplanguage/loop v0.5.0/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
17-
github.com/looplanguage/loop v0.5.1 h1:pCWxUBPalzJQ5Ueo07dyhk15WhwAXpEvocDqShq+x6g=
18-
github.com/looplanguage/loop v0.5.1/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=
1+
github.com/looplanguage/compiler v0.3.0 h1:8DPSpT1hfKFZKJ7bC9bwVZxQEX37Y09jTpPLLCZoPzk=
2+
github.com/looplanguage/compiler v0.3.0/go.mod h1:ICGyV6904dEAY2tJnbCICK/0C7LMzRo8CWsQd55aRFo=
3+
github.com/looplanguage/loop v0.5.2 h1:ZukH3aO9Khf5PgwQF3L33ehOP7PBhZt+FKmyxe1MB7o=
4+
github.com/looplanguage/loop v0.5.2/go.mod h1:H1ENscrP1l2BSqSe4azQ6owr6TkBd7HgaUwDZDeUT6I=

vm/op_add.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ func (vm *VM) OpAdd() error {
2929
}
3030
}
3131

32-
return fmt.Errorf("unknown operation exception. got=%q. got=%q", left.Type(), right.Type())
32+
return fmt.Errorf("unknown operation exception. got=%+v. got=%+v", left, right)
3333
}

vm/run.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,12 @@ func (vm *VM) Run(calledOpcode RanOpcode) error {
155155
case code.OpReturnValue:
156156
returnValue := vm.pop()
157157

158-
frame := vm.popFrame()
159-
vm.sp = frame.basePointer - 1
158+
if vm.frameIndex != 1 {
159+
frame := vm.popFrame()
160+
vm.sp = frame.basePointer - 1
161+
} else {
162+
vm.sp = 0
163+
}
160164

161165
err := vm.push(returnValue)
162166
if err != nil {
@@ -170,6 +174,22 @@ func (vm *VM) Run(calledOpcode RanOpcode) error {
170174
if err != nil {
171175
return err
172176
}
177+
case code.OpSetVar:
178+
index := code.ReadUint16(ins[ip+1:])
179+
180+
vm.currentFrame().ip += 2
181+
182+
vm.variables[index] = vm.pop()
183+
case code.OpGetVar:
184+
index := code.ReadUint16(ins[ip+1:])
185+
186+
vm.currentFrame().ip += 2
187+
188+
if vm.variables[index] == nil {
189+
vm.push(Null)
190+
} else {
191+
vm.push(vm.variables[index])
192+
}
173193
case code.OpSetLocal:
174194
localIndex := code.ReadUint8(ins[ip+1:])
175195
vm.currentFrame().ip += 1

vm/vm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var Null = &object.Null{}
1616

1717
type VM struct {
1818
constants []object.Object
19+
variables []object.Object
1920

2021
stack []object.Object
2122
sp int
@@ -42,6 +43,7 @@ func Create(bytecode *compiler.Bytecode) *VM {
4243
globals: make([]object.Object, GlobalsSize),
4344
frames: frames,
4445
frameIndex: 1,
46+
variables: make([]object.Object, GlobalsSize),
4547
}
4648
}
4749

vm/vm_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ func TestBooleanExpressions(t *testing.T) {
4343

4444
func TestConditionalExpressions(t *testing.T) {
4545
tests := []vmTestCase{
46-
{input: "if (true) { 10 }", expected: 10},
47-
{input: "if (true) { 10 } else { 20 }", expected: 10},
48-
{input: "if (false) { 10 } else { 20 }", expected: 20},
49-
{input: "if (1 > 10) { 10 } else { 20 }", expected: 20},
50-
{input: "if (1 > 10) { 10 } else if(true) { 400 } else { 20 }", expected: 400},
46+
{input: "if (true) { return 10 }", expected: 10},
47+
{input: "if (true) { return 10 } else { 20 }", expected: 10},
48+
{input: "if (false) { return 10 } else { return 20 }", expected: 20},
49+
{input: "if (1 > 10) { return 10 } else { return 20 }", expected: 20},
50+
{input: "if (1 > 10) { return 10 } else if(true) { return 400 } else { return 20 }", expected: 400},
5151
{input: "if (1 > 10) {}", expected: Null},
5252
{input: "if (false) {}", expected: Null},
5353
}
@@ -174,7 +174,7 @@ func TestVM_CallExpressionsWrongArguments(t *testing.T) {
174174
t.Fatalf("compiler error: %s", err)
175175
}
176176
vm := Create(comp.Bytecode())
177-
err = vm.Run()
177+
err = vm.Run(nil)
178178
if err == nil {
179179
t.Fatalf("expected VM error but resulted in none.")
180180
}
@@ -345,7 +345,7 @@ func runVmTests(t *testing.T, tests []vmTestCase) {
345345
}
346346

347347
vm := Create(comp.Bytecode())
348-
err = vm.Run()
348+
err = vm.Run(nil)
349349
if err != nil {
350350
t.Fatalf("vm error: %s", err)
351351
}

0 commit comments

Comments
 (0)