nondescript/src/ndspkg/compiler/expressions.nim

109 lines
2.5 KiB
Nim

{.used.}
import strutils
import bitops # needed for value
import ../scanner
import ../chunk
import ../types/value
import ../config
import types
import utils
import precedence
# EXPRESSIONS
proc number(comp: Compiler) =
# assume the number is already advanced through
let value = comp.previous.text.parseFloat.fromFloat()
comp.writeConstant(value)
tkNumber.genRule(number, nop, pcNone)
proc expFalse(comp: Compiler) =
comp.writeChunk(1, opFalse)
tkFalse.genRule(expFalse, nop, pcNone)
proc expTrue(comp: Compiler) =
comp.writeChunk(1, opTrue)
tkTrue.genRule(expTrue, nop, pcNone)
proc expNil(comp: Compiler) =
comp.writeChunk(1, opNil)
tkNil.genRule(expNil, nop, pcNone)
proc expString(comp: Compiler) =
let value = comp.previous.text[1..^2].fromNimString()
comp.writeConstant(value)
tkString.genRule(expString, nop, pcNone)
proc unary(comp: Compiler) =
let opType = comp.previous.tokenType
comp.parsePrecedence(pcUnary)
case opType:
of tkMinus:
comp.writeChunk(0, opNegate)
of tkBang:
comp.writeChunk(0, opNot)
else:
discard # unreachable
tkBang.genRule(unary, nop, pcNone)
proc binary(comp: Compiler) =
let opType = comp.previous.tokenType
# safety checked in parsePrecedence
let rule = opType.getRule()
comp.parsePrecedence(rule.applyRule.increment)
case opType:
of tkPlus:
comp.writeChunk(-1, opAdd)
of tkMinus:
comp.writeChunk(-1, opSubtract)
of tkStar:
comp.writeChunk(-1, opMultiply)
of tkSlash:
comp.writeChunk(-1, opDivide)
of tkEqualEqual:
comp.writeChunk(-1, opEqual)
of tkBangEqual:
comp.writeChunk(-1, opEqual)
comp.writeChunk(0, opNot)
of tkGreater:
comp.writeChunk(-1, opGreater)
of tkLess:
comp.writeChunk(-1, opLess)
of tkGreaterEqual:
comp.writeChunk(-1, opLess)
comp.writeChunk(0, opNot)
of tkLessEqual:
comp.writeChunk(-1, opGreater)
comp.writeChunk(0, opNot)
else:
return # unreachable
tkMinus.genRule(unary, binary, pcTerm)
tkPlus.genRule(nop, binary, pcTerm)
tkSlash.genRule(nop, binary, pcFactor)
tkStar.genRule(nop, binary, pcFactor)
tkEqualEqual.genRule(nop, binary, pcEquality)
tkBangEqual.genRule(nop, binary, pcEquality)
tkGreater.genRule(nop, binary, pcComparison)
tkGreaterEqual.genRule(nop, binary, pcComparison)
tkLess.genRule(nop, binary, pcComparison)
tkLessEqual.genRule(nop, binary, pcComparison)
proc parseAmpersand(comp: Compiler) =
# just a simple expression separator
discard
tkAmpersand.genRule(nop, parseAmpersand, pcAmpersand)