summaryrefslogtreecommitdiff
path: root/comp/compiler.go
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-12-03 15:28:18 +0100
committerMarc Vertes <mvertes@free.fr>2025-12-03 15:28:18 +0100
commit90284c5bedc5ab7bb442b34ef470744578dcd266 (patch)
tree09f28c2092ed28b0bbcedb15fccd6fb0846e64d2 /comp/compiler.go
parent3d64f909cfb55d8886ac4b4839a98f8f6cdc98e7 (diff)
feat: support literal struct expressions with keyed elements
Diffstat (limited to 'comp/compiler.go')
-rw-r--r--comp/compiler.go24
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())