Add importing, lists and objects, and add basic functions (global and on values)

This commit is contained in:
Neemek 2025-03-10 16:23:16 +01:00
parent 449f7cd815
commit 634a4a2b61
Signed by: neemek
GPG key ID: 28360A8951CD0E9B
11 changed files with 919 additions and 60 deletions

View file

@ -5,9 +5,16 @@ type Compiler struct {
ip Pos
scope Pos
imports map[string]Node
resolver ImportsResolver
stack *Stack[LocalVariable]
}
type ImportsResolver interface {
Resolve(path string) (Node, error)
}
type LocalVariable struct {
name string
scope int
@ -15,10 +22,11 @@ type LocalVariable struct {
func NewCompiler() *Compiler {
c := &Compiler{
Chunk: NewChunk(make([]Bytecode, 0), make([]Value, 0)),
ip: 0,
scope: 0,
stack: NewStack[LocalVariable](256),
Chunk: NewChunk(make([]Bytecode, 0), make([]Value, 0)),
ip: 0,
scope: 0,
stack: NewStack[LocalVariable](256),
imports: make(map[string]Node),
}
return c
@ -63,6 +71,14 @@ func (c *Compiler) Compile(tree Node) {
c.add(InstructionConstant)
c.addConstant(tree.(*NumberNode).value)
case ListNodeType:
v := tree.(*ListNode).items
c.add(InstructionNewList)
for _, n := range v {
c.Compile(n)
c.add(InstructionAppend)
}
case ReferenceNodeType:
c.getVar(tree.(*ReferenceNode).name)
@ -155,7 +171,7 @@ func (c *Compiler) Compile(tree Node) {
c.Compile(arg)
}
c.getVar(n.name)
c.Compile(n.source)
c.add(InstructionCall)
@ -194,12 +210,28 @@ func (c *Compiler) Compile(tree Node) {
n.name,
n.params,
c.Chunk,
nil,
}
// restore old chunk and ip
c.Chunk = mc
c.ip = mip
case AccessNodeType:
n := tree.(*AccessNode)
c.Compile(n.source)
c.add(InstructionAccessProperty)
c.addConstant(StringValue(n.property))
case ImportNodeType:
n := tree.(*ImportNode)
t := c.resolveImport(n.path).(*BlockNode)
for _, statement := range t.statements {
c.Compile(statement)
}
case ReturnNodeType:
c.Compile(tree.(*ReturnNode).value)
c.add(InstructionReturn)
@ -305,6 +337,26 @@ func (c *Compiler) descend() {
}
}
func (c *Compiler) resolveImport(path string) Node {
if chunk, ok := c.imports[path]; ok {
return chunk
}
// find tree
tree, err := c.resolver.Resolve(path)
if err != nil {
panic(err)
}
c.imports[path] = tree
return tree
}
func (c *Compiler) SetImportsResolver(resolver ImportsResolver) {
c.resolver = resolver
}
func (c *Compiler) advance(amount Pos) {
c.ip += amount
}