113 lines
2.7 KiB
Nim
113 lines
2.7 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)
|
|
when debugCompiler:
|
|
debugEcho &"Written constant (type: {value.ndType}, str repr: {$value}) to chunk"
|
|
|
|
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)
|
|
when debugCompiler:
|
|
debugEcho &"Written constant (type: {value.ndType}, str repr: {$value}) to chunk"
|
|
|
|
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) |