Add importing, lists and objects, and add basic functions (global and on values)
This commit is contained in:
parent
449f7cd815
commit
634a4a2b61
11 changed files with 919 additions and 60 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue