diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-12-03 15:28:18 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-12-03 15:28:18 +0100 |
| commit | 90284c5bedc5ab7bb442b34ef470744578dcd266 (patch) | |
| tree | 09f28c2092ed28b0bbcedb15fccd6fb0846e64d2 /comp/compiler.go | |
| parent | 3d64f909cfb55d8886ac4b4839a98f8f6cdc98e7 (diff) | |
feat: support literal struct expressions with keyed elements
Diffstat (limited to 'comp/compiler.go')
| -rw-r--r-- | comp/compiler.go | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/comp/compiler.go b/comp/compiler.go index 7b12086..7c21d46 100644 --- a/comp/compiler.go +++ b/comp/compiler.go @@ -48,6 +48,7 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) { log.Println("Codegen tokens:", tokens) fixList := parser.Tokens{} // list of tokens to fix after all necessary information is gathered stack := []*parser.Symbol{} // for symbolic evaluation, type checking, etc + keyList := []string{} emit := func(t scanner.Token, op vm.Op, arg ...int) { _, file, line, _ := runtime.Caller(1) @@ -152,14 +153,31 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) { } emit(t, vm.CallX, t.Beg) + case lang.Colon: + // Keyed element in a literal composite expression: + // If the key is an ident (field name), then push it on the keystack, + // to be computed at compile time in Composite handling. + // Or generate instructions so key will be computed at runtime. + if tokens[i-1].Tok == lang.Ident { + keyList = append(keyList, tokens[i-1].Str) + } + case lang.Composite: d := top() // let the type symbol on the stack, may be required for assignment switch d.Type.Rtype.Kind() { case reflect.Struct: emit(t, vm.Fnew, d.Index) - nf := d.Type.Rtype.NumField() - for i := 0; i < nf; i++ { - emit(t, vm.FieldSet, i) + if len(keyList) == 0 { + nf := d.Type.Rtype.NumField() + for i := 0; i < nf; i++ { + emit(t, vm.FieldSet, i) + } + } else { + for _, fname := range keyList { + i := d.Type.FieldNameIndex(fname) + emit(t, vm.FieldSet, i...) + } + keyList = []string{} } default: return fmt.Errorf("composite kind not supported yet: %v", d.Type.Rtype.Kind()) |
