nondescript/src/ndspkg/compiler/types.nim

91 lines
2.8 KiB
Nim

import sugar
import ../scanner
import ../chunk
type
Local* = ref object
name*: string # name of this local
index*: int # what is its index in the stack (0 is the stack bottom - nil in the main function)
depth*: int # depth of this local
# if depth is -1, the variable cannot be referenced yet
# its depth will be set once its first ever value is determined
scope*: Scope # the innermost scope of this local
captured*: bool
Upvalue* = ref object
index*: int
isLocal*: bool
Scope* = ref object
labels*: seq[string]
goalStackIndex*: int # the stack count it started with plus 1
jumps*: seq[int] # jumps to be patched that jump to the end
function*: bool # if true, it is a function
parentFunction*: Scope # if not a function, which scope is the innermost function it's in (if it's a function this points to itself)
# if parentFunction is nil, the scope is not inside a function
upvalues*: seq[Upvalue] # only needed for functions
Compiler* = ref object
#
# input
#
scanner*: Scanner
source*: string
#
# state
#
previous*: Token
current*: Token
canAssign*: bool
locals*: seq[Local]
scopes*: seq[Scope]
stackIndex*: int # how large the stack is
# when there's an error both are set
# panic mode can be turned off e.g. at block boundaries
panicMode*: bool
#
# output
#
chunk*: Chunk
hadError*: bool
Precedence* = enum
pcNone, pcExprTop, pcAmpersand, pcAssignment, pcNonAssignTop, pcOr, pcAnd, pcEquality, pcComparison,
pcTerm, pcFactor, pcUnary, pcCall, pcIndex, pcPrimary
# pcUnary applies to all prefix operators regardless of this enum's value
# changing pcUnary's position can change the priority of all unary ops
#
# Note: unary only rules should have precedence pcNone!!!
# pcExprTop, pcNonAssignTop are special placeholders!
ParseRule* = object
name*: string # debug purposes only
prefix*: (Compiler) -> void
infix*: (Compiler) -> void
prec*: Precedence # only relevant to infix, prefix always has pcUnary
proc newScope*(comp: Compiler, function: bool): Scope =
result.new()
#result.depth = comp.scopes.len + 1
result.function = function
result.goalStackIndex = comp.stackIndex + 1
if function:
result.parentFunction = result
elif comp.scopes.len() > 0 and comp.scopes[comp.scopes.high()].parentFunction != nil:
result.parentFunction = comp.scopes[comp.scopes.high()].parentFunction
comp.scopes.add(result)
# HELPERS FOR THE COMPILER TYPE
proc newCompiler*(name: string, source: string): Compiler =
result = new(Compiler)
result.chunk = initChunk(name)
result.source = source
result.hadError = false
result.panicMode = false
result.canAssign = true
result.locals = @[]
result.scopes = @[]