92 lines
2.5 KiB
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) |