nondescript/src/ndspkg/compiler/collections.nim

92 lines
2.5 KiB
Nim

{.used.}
import ../scanner
import ../chunk
import ../types/value
import bitops
import types
import utils
import precedence
# lists
proc parseList(comp: Compiler) =
var count: int
while comp.current.tokenType != tkRightBracket:
comp.expression()
count.inc()
if comp.current.tokenType != tkRightBracket:
comp.consume(tkComma, "Comma expected after list member.")
comp.consume(tkRightBracket, "Right bracket expected after list members.")
if count > argMax:
comp.error("Maximum list length exceeded.")
comp.writeChunk(1 - count, opCreateList)
comp.writeChunk(0, count.toDU8())
tkStartList.genRule(parseList, nop, pcNone)
# tables
proc parseTable(comp: Compiler) =
var count: int
while comp.current.tokenType notin {tkEof, tkRightBrace}:
if comp.match(tkLeftBracket):
comp.expression()
comp.consume(tkRightBracket, "Expect ']' after key.")
elif comp.match(tkIdentifier):
let ident = comp.previous.text.fromNimString()
comp.writeConstant(ident)
else:
comp.error("Key expected in table (perhaps you forgot to encapsulate the key with []?).")
if not comp.match(tkColon):
comp.consume(tkEqual, "Equal sign or colon expected after key.")
comp.expression()
count.inc()
if comp.current.tokenType != tkRightBrace:
comp.consume(tkComma, "Comma expected after key-value pair.")
comp.consume(tkRightBrace, "Right brace expected after table members.")
if count > argMax:
comp.error("Maximum table length exceeded.")
comp.writeChunk(1 - 2 * count, opCreateTable)
comp.writeChunk(0, count.toDU8())
tkStartTable.genRule(parseTable, nop, pcNone)
# len op
proc parseLen(comp: Compiler) =
comp.expression()
comp.writeChunk(0, opLen)
tkHashtag.genRule(parseLen, nop, pcNone)
# get/set index
proc parseIndex(comp: Compiler) =
# the index
comp.expression()
comp.consume(tkRightBracket, "Right bracket expected after index.")
if comp.match(tkEqual):
comp.parsePrecedence(pcNonAssignTop)
comp.writeChunk(-2, opSetIndex)
else:
comp.writeChunk(-1, opGetIndex)
tkLeftBracket.genRule(nop, parseIndex, pcIndex)
proc parseDotIndex(comp: Compiler) =
# the index
comp.consume(tkIdentifier, "Identifier expected after dot index.")
let index = comp.previous.text.fromNimString()
comp.writeConstant(index)
if comp.match(tkEqual):
comp.parsePrecedence(pcNonAssignTop)
comp.writeChunk(-2, opSetIndex)
else:
comp.writeChunk(-1, opGetIndex)
tkDot.genRule(nop, parseDotIndex, pcIndex)