diff options
| author | Marc Vertes <mvertes@free.fr> | 2024-07-18 12:56:29 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 12:56:29 +0200 |
| commit | dabd9e5eb81bbc9aeaeb32fb3e3ce83eef258a77 (patch) | |
| tree | 32be6a4cecf83487dd6a91e8a9aa1da709840b0f /parser/compiler.go | |
| parent | 1a2b2cb565ebf701f43012e1fce5552398d622a9 (diff) | |
fix (parser): don't panic if assign of define untyped value (#10)
* fix (parser): don't panic if assign of define untyped value
In case of defining or assigning to untyped value, the type has
to be taken from the source value instead of the target value.
The vm test coverage has also been slightly improved.
* fix and simplify Token.Name()
* improve parser errors
Diffstat (limited to 'parser/compiler.go')
| -rw-r--r-- | parser/compiler.go | 25 |
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} |
