diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 7a3f322..e8ab19f 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -215,8 +215,11 @@ func newStruct( v := ctx.gen(value) if _, ok := v.(*ir.InstBitCast); ok { - ctx.block.NewStore(nullStructPtr, fieldPtr) - ctx.block.NewStore(v, fieldPtr) + if p, ok := structCtx.Field[field.Val].Type.(*types.PointerType); ok { + nullFieldPtr := constant.NewNull(p) + ctx.block.NewStore(nullFieldPtr, fieldPtr) + ctx.block.NewStore(v, fieldPtr) + } } else { ctx.block.NewStore(v, fieldPtr) } @@ -345,6 +348,8 @@ func (ctx *Context) genStructTypeDeclare(node *mTypes.Node) { // need to check others struct if rootTy == nil && n.IsType(mTypes.TY_EXTENDED) && n.Type.ExtendName == node.Val { rootTy = structType + } else if rootTy == nil { + rootTy = mTypes.GetExtendedType(ctx.prog.Declare, n).Types } f := structField[n.Val] f.Pos = pos diff --git a/pkg/parser/validator.go b/pkg/parser/validator.go index a61e863..635cf8e 100644 --- a/pkg/parser/validator.go +++ b/pkg/parser/validator.go @@ -35,6 +35,9 @@ func findTypeDeclare(n *mTypes.Node, targetType string) *mTypes.Node { if n.IsKind(mTypes.ND_TYPE_DECLARE) && n.Val == targetType { return n } + if result := findTypeDeclare(n.Next, targetType); result != nil { + return result + } if result := findTypeDeclare(n.Child, targetType); result != nil { return result } diff --git a/script/test-full.sh b/script/test-full.sh index 86aedd1..418f04f 100755 --- a/script/test-full.sh +++ b/script/test-full.sh @@ -284,6 +284,7 @@ testexec(){ assertexec '(defschema Person {:name :: string :age :: int :isMale :: bool}) (def f :: Person (fn [] (let [node :: Person {:age 20 :name "richard" :isMale true}] node))) (def main :: int (fn [] (prn (get f :age))))' "20\\\n" assertexec '(defschema Person {:name :: string :age :: int :isMale :: bool :height :: double :v :: [int]}) (def main :: int (fn [] (let [node :: Person {:age 20 :name "richard" :isMale true :height 5.8 :v [4, 3, 2]}] (prn (get node :name)) (prn (get node :age)) (prn (get node :isMale)) (prn (get node :height)) (prn (get node :v)) )))' "richard\\\n20\\\ntrue\\\n5.8\\\n[4, 3, 2]\\\n" assertexec '(defschema Person {:name ::string :next ::Person})(def main ::int (fn [] (let [node ::Person {:name "richard" :next {:name "rebecca" :next {:name "andre" :next {:name "bob"}}}}] (prn (get node :name)) (prn (get (get node :next) :name)) (prn (get (get (get node :next) :next) :name)) (prn (get (get (get (get node :next) :next) :next) :name)))))' "richard\\\nrebecca\\\nandre\\\nbob\\\n" + assertexec '(defschema Country {:name ::string})(defschema Person {:name ::string :country ::Country})(def main ::int (fn [] (let [c ::Country {:name "deutsch"} person ::Person {:name "mike" :country c}] (prn (get (get person :country) :name)))))' "deutsch\\\n" ############# # Prelude functions