Skip to content

Commit

Permalink
add support for iterable ranges for $i in 0..100
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Mar 22, 2024
1 parent bbf3dab commit afc2d6c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
11 changes: 10 additions & 1 deletion src/tim/engine/compilers/html.nim
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,15 @@ template loopEvaluator(kv, items: Node) =
node.loopItem.identPairs[1].varValue = nil
handleBreakCommand(x)
else: discard
of ntIndexRange:
for i in items.rangeNodes[0].iVal .. items.rangeNodes[1].iVal:
newScope(scopetables)
node.loopItem.varValue = ast.newInteger(i)
c.varExpr(node.loopItem, scopetables)
let x = c.walkNodes(node.loopBody, scopetables)
clearScope(scopetables)
node.loopItem.varValue = nil
handleBreakCommand(x)
else:
let x = @[ntLitString, ntLitArray, ntLitObject]
compileErrorWithArgs(typeMismatch, [$(items.nt), x.join(" ")])
Expand All @@ -934,7 +943,7 @@ proc evalLoop(c: var HtmlCompiler, node: Node,
of ntBracketExpr:
let items = c.bracketEvaluator(node.loopItems, scopetables)
loopEvaluator(node.loopItem, items)
of ntLitString:
of ntLitString, ntIndexRange:
loopEvaluator(node.loopItem, node.loopItems)
else:
compileErrorWithArgs(invalidIterator)
Expand Down
42 changes: 33 additions & 9 deletions src/tim/engine/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@ type
Parser* = object
lvl: int # parser internals
lex: Lexer
## A pkg/toktok instance
# A pkg/toktok instance
prev, curr, next: TokenTuple
## Lexer internals
# Lexer internals
engine: TimEngine
## TimEngine instance
# TimEngine instance
tpl: TimTemplate
## A `TimTemplate` instance that represents the
## currently parsing template
# A `TimTemplate` instance that represents the
# currently parsing template
logger*: Logger
## Store warning and errors while parsing
hasErrors*, nilNotError, hasLoadedView,
isMain, refreshAst: bool
parentNode: seq[Node]
## Parser internals
# Parser internals
includes: Table[string, Meta]
## A table to store all `@include` statements
# A table to store all `@include` statements
tree: Ast
## The generated Abstract Syntax Tree
# The generated Abstract Syntax Tree

PrefixFunction = proc(p: var Parser, excludes, includes: set[TokenKind] = {}): Node {.gcsafe.}
InfixFunction = proc(p: var Parser, lhs: Node): Node {.gcsafe.}
Expand Down Expand Up @@ -703,11 +703,24 @@ prefixHandle pFor:
pairNode.identPairs[1] = vNode
result.loopItem = pairNode
walk p
let inx = p.curr
expectWalk tkIN
expect {tkIdentVar, tkString, tkLB}: # todo function call
if p.curr in {tkIdentVar, tkString, tkLB}:
# expect {tkIdentVar, tkString, tkLB, tkInteger}: # todo function call
let items = p.parsePrefix()
caseNotNil items:
result.loopItems = items
elif p.curr is tkInteger and p.curr.line == inx.line:
let min = p.curr; walk p
if likely(isRange()):
walk p, 2
expect tkInteger:
result.loopItems = ast.newNode(ntIndexRange)
result.loopItems.rangeNodes = [
ast.newInteger(min.value.parseInt, min),
ast.newInteger(p.curr.value.parseInt, p.curr)
]
walk p
if p.curr is tkColon: walk p
while p.curr.isChild(tk):
let node = p.getPrefixOrInfix()
Expand Down Expand Up @@ -814,6 +827,15 @@ prefixHandle pInclude:
walk p
else: return nil

prefixHandle pImport:
# parse `@import`
if likely p.next is tkString:
let tk = p.curr
walk p
result = ast.newNode(ntImport, tk)
add result.modules, p.curr.value
walk p

prefixHandle pSnippet:
case p.curr.kind
of tkSnippetJS:
Expand Down Expand Up @@ -1051,6 +1073,7 @@ proc getPrefixFn(p: var Parser, excludes, includes: set[TokenKind] = {}): Prefix
of tkViewLoader: pViewLoader
of tkSnippetJS, tkSnippetJSON, tkSnippetYaml: pSnippet
of tkInclude: pInclude
of tkImport: pImport
of tkClient: pClientSide
of tkLB: pAnoArray
of tkLC: pAnoObject
Expand Down Expand Up @@ -1100,6 +1123,7 @@ proc parseRoot(p: var Parser, excludes, includes: set[TokenKind] = {}): Node {.g
p.pElement()
of tkSnippetJS: p.pSnippet()
of tkInclude: p.pInclude()
of tkImport: p.pImport()
of tkLB: p.pAnoArray()
of tkLC: p.pAnoObject()
of tkFN, tkFunc: p.pFunction()
Expand Down

0 comments on commit afc2d6c

Please sign in to comment.