From 90284c5bedc5ab7bb442b34ef470744578dcd266 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 3 Dec 2025 15:28:18 +0100 Subject: feat: support literal struct expressions with keyed elements --- comp/compiler.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'comp/compiler.go') 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()) -- cgit v1.2.3