From a3da295cdab55466e9f0586c2dfc2ccad8b8472b Mon Sep 17 00:00:00 2001 From: Hidetatz Yaginuma Date: Wed, 6 Sep 2023 10:34:22 +0900 Subject: [PATCH] wip support struct field selection --- process.go | 34 +++++++++++++++++++++++----------- tests/struct.sb | 3 ++- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/process.go b/process.go index afa1bcb..2c60efa 100644 --- a/process.go +++ b/process.go @@ -656,22 +656,34 @@ func procSelector(mod *module, n *ndSelector) (procResult, shibaErr) { return nil, err } - // currently selector typ must be mod. - // In the future this should support struct/field. - if selector.typ != tMod { - return nil, &errSimple{msg: fmt.Sprintf("selector %s is not a module", selector), l: n.token().loc} - } + if selector.typ == tMod { + target, err := procAsObj(selector.mod, n.target) + if err != nil { + return nil, err + } - target, err := procAsObj(selector.mod, n.target) - if err != nil { - return nil, err + if target != nil { + return &prObj{o: target}, nil + } + + return nil, nil } - if target != nil { - return &prObj{o: target}, nil + if selector.typ == tStruct { + field, ok := n.target.(*ndIdent) + if !ok { + return nil, &errSimple{msg: fmt.Sprintf("%s must be an identifier", n.target), l: n.token().loc} + } + + f, ok := selector.fields[field.ident] + if !ok { + return nil, &errSimple{msg: fmt.Sprintf("unknown field name %s in %s", field.ident, selector), l: n.token().loc} + } + + return &prObj{o: f}, nil } - return nil, nil + return nil, &errSimple{msg: fmt.Sprintf("selector %s is not a module", selector), l: n.token().loc} } func procFuncall(mod *module, n *ndFuncall) (procResult, shibaErr) { diff --git a/tests/struct.sb b/tests/struct.sb index cb62bd4..7e742e0 100644 --- a/tests/struct.sb +++ b/tests/struct.sb @@ -20,6 +20,7 @@ struct person{ } p = person{name: "alice", age: 3} -print(p) +as("alice", p.name) +as(3, p.age) print("struct test succeeded")