55#
66# (c) 2025 George Lemon | LGPL-v3 License
77# Made by Humans from OpenPeeps
8- # https://github.com/openpeeps/tim | https://tim-engine.com
8+ # https://github.com/openpeeps/tim | https://openpeeps.dev/packages/tim
99
1010import std/ [macros, options, os, hashes,
1111 sequtils, strutils, ropes, tables, json]
@@ -190,11 +190,6 @@ proc addSym(gen: var CodeGen, sym: Sym,
190190 if not gen.module.add (sym, name):
191191 name.error (ErrGlobalRedeclaration % [$ name])
192192
193- #
194- # Forward declarations
195- #
196- proc genGetField (node: Node ): Sym {.codegen .}
197-
198193proc newProc * (script: Script , name, impl: Node ,
199194 params: seq [ProcParam ], returnTy: Sym ,
200195 kind: ProcKind , exported = false ,
@@ -328,6 +323,7 @@ proc genIterator(node: Node, isInstantiation = false): Sym {.codegen.}
328323proc genObject (node: Node , isInstantiation = false ): Sym {.codegen .}
329324proc genObjectStorage (node: Node , isInstantiation = false ): Sym {.codegen .}
330325proc genArray (node: Node , isInstantiation = false ): Sym {.codegen .}
326+ proc genGetField (node: Node ): Sym {.codegen .}
331327proc genTypeDef (node: Node ): Sym {.codegen .}
332328proc htmlConstr (node: Node ): Sym {.codegen .}
333329
@@ -473,7 +469,10 @@ proc lookup(gen: var CodeGen, symName: Node, quiet = false): Sym =
473469 # find out the symbol's name
474470 var name: Node
475471 case symName.kind
476- of nkIdent: name = symName # regular ident
472+ of nkIdent:
473+ name = symName # regular ident
474+ of nkCall:
475+ name = symName[0 ] # function call
477476 of nkVarTy: name = symName.varType
478477 of nkIndex:
479478 if symName[0 ].kind == nkIndex:
@@ -710,7 +709,8 @@ proc splitCall(ast: Node): tuple[callee: Sym, args: seq[Node]] {.codegen.} =
710709 ast[1 ].error (" Use bracket notation to access JSON fields or items" )
711710 else :
712711 callee = ast[1 ]
713- args = @ [ast[0 ]]
712+ args.add (ast[0 ])
713+ args.add (ast[1 ][1 ..^ 1 ])
714714 of nkBracket:
715715 # this is an array access, so we return the array and the index
716716 # as the callee and the argument, respectively
@@ -1090,10 +1090,24 @@ proc call(node: Node): Sym {.codegen.} =
10901090proc genGetField (node: Node ): Sym {.codegen .} =
10911091 # Generate code for field access.
10921092 # all fields must be idents, so we check for that.
1093+ case node[1 ].kind
1094+ of nkCall:
1095+ let (fnSym, fnParams) = gen.splitCall (node)
1096+ var argTypes: seq [Sym ]
1097+ for arg in fnParams:
1098+ argTypes.add (gen.genExpr (arg))
1099+ return gen.callProc (fnSym, argTypes, node)
1100+ else : discard
10931101 if node[1 ].kind notin {nkIdent, nkBracket}:
10941102 node[1 ].error (ErrInvalidField % $ node[1 ])
1095- let typeSym = gen.genExpr (node[0 ]) # generate the left-hand side
1096-
1103+ var valTy = gen.genExpr (node[0 ]) # generate the left-hand side
1104+ var varTy: SymKind
1105+ case valTy.kind
1106+ of skVars:
1107+ varTy = valTy.kind
1108+ valTy = valTy.varTy
1109+ else : discard
1110+
10971111 # get the field's name
10981112 var fieldName: string
10991113 if node[1 ].kind == nkIdent:
@@ -1102,12 +1116,11 @@ proc genGetField(node: Node): Sym {.codegen.} =
11021116 # if the field is accessed using the bracket notation, we use the ident
11031117 # inside the brackets as the field name
11041118 fieldName = node[1 ][0 ].ident
1105-
11061119 # only objects have fields. we also check if the given object *does* have the
11071120 # field in question, and generate an error if not
1108- if typeSym .tyKind == tyObject and typeSym .objectFields.hasKey (fieldName):
1121+ if valTy .tyKind == tyObject and valTy .objectFields.hasKey (fieldName):
11091122 # we use the getF opcode to push fields onto the stack.
1110- let field = typeSym .objectFields[fieldName]
1123+ let field = valTy .objectFields[fieldName]
11111124 result = field.ty
11121125 gen.chunk.emit (opcGetF)
11131126 gen.chunk.emit (field.id.uint8 )
@@ -1116,8 +1129,8 @@ proc genGetField(node: Node): Sym {.codegen.} =
11161129 # an appropriate proc that will retrieve it for us
11171130 let getter = gen.lookup (node[1 ])
11181131 if getter == nil :
1119- node[1 ].error (ErrNonExistentField % [fieldName, $ typeSym ])
1120- result = gen.callProc (getter, argTypes = @ [typeSym ], errorNode = node)
1132+ node[1 ].error (ErrNonExistentField % [fieldName, $ valTy ])
1133+ result = gen.callProc (getter, argTypes = @ [valTy ], errorNode = node)
11211134
11221135proc genArrayAccess (node: Node ): Sym {.codegen .} =
11231136 # Generate code for array access.
@@ -1130,7 +1143,12 @@ proc genArrayAccess(node: Node): Sym {.codegen.} =
11301143 of skVars:
11311144 valTy = valTy.varTy
11321145 else : discard
1133-
1146+
1147+ case indexTy.kind
1148+ of skVars:
1149+ indexTy = indexTy.varTy
1150+ else : discard
1151+
11341152 case valTy.tyKind
11351153 of tyJson:
11361154 # generate the code for accessing a JSON array
@@ -1644,7 +1662,8 @@ proc genExpr(node: Node, varUnwrap = false): Sym {.codegen.} =
16441662 else : symNode)
16451663 of nkPrefix: # prefix operators
16461664 result = gen.prefix (node)
1647- of nkInfix: # infix operators
1665+ of nkInfix:
1666+ # handle infix expressions
16481667 result = gen.infix (node)
16491668 of nkDot:
16501669 # generate code for object/class field access
0 commit comments