Skip to content

Commit

Permalink
Add IndexRange [0..^2]
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Mar 6, 2024
1 parent 4311d8b commit 6d138a1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 21 deletions.
8 changes: 6 additions & 2 deletions src/tim/engine/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ type
ntIdent = "Identifier"
ntCall = "FunctionCall"
ntIdentPair
ntDotExpr
ntBracketExpr
ntDotExpr = "DotExpression"
ntBracketExpr = "BracketExpression"
ntIndexRange = "IndexRange"
ntConditionStmt = "ConditionStatement"
ntLoopStmt = "LoopStmt"
ntViewLoader = "ViewLoader"
Expand Down Expand Up @@ -153,6 +154,9 @@ type
of ntBracketExpr:
bracketStorageType*: StorageType
bracketLHS*, bracketIndex*: Node
of ntIndexRange:
rangeNodes*: array[2, Node]
rangeLastIndex*: bool # from end to start using ^ circumflex accent
of ntLitFunction:
fnIdent*: string
fnParams*: OrderedTable[string, FnParam]
Expand Down
15 changes: 14 additions & 1 deletion src/tim/engine/compilers/html.nim
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,19 @@ proc walkAccessorStorage(c: var HtmlCompiler,
result = lhs.arrayItems[rhs.iVal]
except Defect:
compileErrorWithArgs(indexDefect, lhs.meta, [$(rhs.iVal), "0.." & $(lhs.arrayItems.high)])
of ntIndexRange:
let l = rhs.rangeNodes[0].iVal
let r = rhs.rangeNodes[1].iVal
try:
result = ast.newNode(ntLitArray)
result.meta = lhs.meta
case rhs.rangeLastIndex
of false:
result.arrayItems = lhs.arrayItems[l..r]
of true:
result.arrayItems = lhs.arrayItems[l..^r]
except Defect:
compileErrorWithArgs(indexDefect, lhs.meta, ["", "0.." & $(lhs.arrayItems.high)])
else: compileErrorWithArgs(invalidAccessorStorage, rhs.meta, [rhs.toString, $lhs.nt])
else: discard

Expand Down Expand Up @@ -544,7 +557,7 @@ proc getValue(c: var HtmlCompiler, node: Node,
if likely(some.scopeTable != nil):
return c.getValue(some.scopeTable[node.identName].varValue, scopetables)
compileErrorWithArgs(undeclaredVariable, [node.identName])
of ntAssignableSet:
of ntAssignableSet, ntIndexRange:
# return literal nodes
result = node
of ntInfixExpr:
Expand Down
56 changes: 38 additions & 18 deletions src/tim/engine/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ proc `notin`(tk: TokenTuple, kind: set[TokenKind]): bool {.inline.} =
proc isFnCall(p: var Parser): bool {.inline.} =
p.curr is tkIdentifier and p.next is tkLP and p.next.wsno == 0

template isRange: untyped =
(
(p.curr is tkDot and p.next is tkDot) and
(p.curr.line == tk.line and p.next.line == tk.line)
)

template expectWalk(kind: TokenKind) =
if likely(p.curr is kind):
walk p
Expand Down Expand Up @@ -262,25 +268,39 @@ proc parseDotExpr(p: var Parser, lhs: Node): Node {.gcsafe.} =

proc parseBracketExpr(p: var Parser, lhs: Node): Node {.gcsafe.} =
# parse bracket expression
result = ast.newNode(ntBracketExpr, p.prev)
walk p # tkLB
let tk = p.curr; walk p # tkLB
let index = p.getPrefixOrInfix()
result = ast.newNode(ntBracketExpr, p.curr)
result.bracketLHS = lhs
caseNotNil index:
result.bracketIndex = index
result.bracketLHS = lhs
expectWalk tkRB
while true:
case p.curr.kind
of tkDot:
if p.curr.line == result.meta[0]:
result = p.parseDotExpr(result)
else: break
of tkLB:
if p.curr.line == result.meta[0]:
result = p.parseBracketExpr(result)
else: break
else:
break # todo handle infix expressions
if p.curr is tkRB:
result.bracketIndex = index
while true:
case p.curr.kind
of tkDot:
if p.curr.line == result.meta[0]:
result = p.parseDotExpr(result)
else: break
of tkLB:
if p.curr.line == result.meta[0]:
result = p.parseBracketExpr(result)
else: break
else:
break # todo handle infix expressions
elif isRange:
walk p, 2
let lastIndex =
if p.curr is tkCaret:
walk p; true
else: false
expect {tkInteger, tkIdentVar}:
let rhs = p.parsePrefix()
caseNotnil rhs:
let rangeNode = ast.newNode(ntIndexRange)
rangeNode.rangeNodes = [index, rhs]
rangeNode.rangeLastIndex = lastIndex
result.bracketIndex = rangeNode
expectWalk tkRB

prefixHandle pIdent:
# parse an identifier
Expand Down Expand Up @@ -592,7 +612,7 @@ prefixHandle pFor:
pairNode.identPairs[1] = vNode
result.loopItem = pairNode
walk p
expectWalk(tkIN)
expectWalk tkIN
expect {tkIdentVar, tkLB}:
let items = p.parsePrefix()
caseNotNil items:
Expand Down
1 change: 1 addition & 0 deletions src/tim/engine/tokens.nim
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ registerTokens toktokSettings:
doc = tokenize(handleDocBlock, '*')
comment = tokenize(handleInlineComment, '/')
`mod` = '%'
caret = '^'
lc = '{'
rc = '}'
lp = '('
Expand Down

0 comments on commit 6d138a1

Please sign in to comment.