nondescript/src/ndspkg/compiler/expressions.nim

118 lines
2.9 KiB
Nim

# THIS MODULE IS TO BE SPLIT UP LATER
import strformat
import strutils
import bitops # needed for value
import ../scanner
import ../chunk
import ../types/value
import ../config
# the following order of imports here is important
# it defines the allowed dependency precedence between the compiler files
import types
import utils
import precedence
import jumps
import scope
# 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)