summaryrefslogtreecommitdiff
path: root/parser/compiler.go
diff options
context:
space:
mode:
Diffstat (limited to 'parser/compiler.go')
-rw-r--r--parser/compiler.go25
1 files changed, 17 insertions, 8 deletions
diff --git a/parser/compiler.go b/parser/compiler.go
index 3b9a32d..05462eb 100644
--- a/parser/compiler.go
+++ b/parser/compiler.go
@@ -61,13 +61,14 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
case lang.String:
s := t.Block()
+ v := vm.Value{Data: reflect.ValueOf(s), Type: vm.TypeOf(s)}
i, ok := c.strings[s]
if !ok {
i = len(c.Data)
- c.Data = append(c.Data, vm.ValueOf(s))
+ c.Data = append(c.Data, v)
c.strings[s] = i
}
- push(&symbol{kind: symConst, value: vm.ValueOf(s)})
+ push(&symbol{kind: symConst, value: v})
emit(int64(t.Pos), vm.Dup, int64(i))
case lang.Add:
@@ -144,7 +145,11 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
// TODO: support assignment to local, composite objects.
st := tokens[i-1]
l := len(c.Data)
- typ := pop().Type
+ d := pop()
+ typ := d.Type
+ if typ == nil {
+ typ = d.value.Type
+ }
v := vm.NewValue(typ)
c.addSym(l, st.Str, v, symVar, typ, false)
c.Data = append(c.Data, v)
@@ -160,7 +165,11 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
if !ok {
return fmt.Errorf("symbol not found: %s", st.Str)
}
- typ := pop().Type
+ d := pop()
+ typ := d.Type
+ if typ == nil {
+ typ = d.value.Type
+ }
if s.Type == nil {
s.Type = typ
s.value = vm.NewValue(typ)
@@ -259,7 +268,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
} else {
i = s.value.Data.Int() - int64(len(c.Code))
}
- emit(int64(t.Pos), vm.JumpSetTrue, int64(i))
+ emit(int64(t.Pos), vm.JumpSetTrue, i)
case lang.Goto:
var i int64
@@ -431,17 +440,17 @@ type DumpValue struct {
// This design choice allows the Virtual Machine (VM) to evolve its memory management strategies
// without compromising backward compatibility with dumps generated by previous versions.
func (c *Compiler) Dump() *Dump {
- var dv []*DumpValue
dict := c.symbolsByIndex()
+ dv := make([]*DumpValue, len(c.Data))
for i, d := range c.Data {
e := dict[i]
- dv = append(dv, &DumpValue{
+ dv[i] = &DumpValue{
Index: e.index,
Name: e.name,
Kind: int(e.kind),
Type: e.Type.Name,
Value: d.Data.Interface(),
- })
+ }
}
return &Dump{Values: dv}