fix imports

This commit is contained in:
Neemek 2025-03-31 10:58:13 +02:00
parent 49c15f6fb6
commit c364e09fc9
Signed by: neemek
GPG key ID: 28360A8951CD0E9B
3 changed files with 48 additions and 20 deletions

View file

@ -42,12 +42,12 @@ func (r *WorkingDirectoryResolver) IsSame(a, b string) bool {
return apath == bpath
}
func makeChunk(ctx *Context, filepath string, ignoreWarnings bool) (*core.Chunk, error) {
func makeChunk(ctx *Context, fpath string, ignoreWarnings bool) (*core.Chunk, error) {
if ctx.Debug {
log.Println("Reading file")
}
f, err := os.ReadFile(filepath)
f, err := os.ReadFile(fpath)
if err != nil {
return nil, err
@ -83,7 +83,12 @@ func makeChunk(ctx *Context, filepath string, ignoreWarnings bool) (*core.Chunk,
log.Println("Initialized parser")
}
tree, err := p.Parse()
pathat, err := filepath.Abs(fpath)
if err != nil {
return nil, err
}
tree, err := p.Parse(pathat)
if ctx.Debug {
log.Printf("Parsed tree, meaning:\n%s", tree)
@ -104,7 +109,7 @@ func makeChunk(ctx *Context, filepath string, ignoreWarnings bool) (*core.Chunk,
log.Println("Setting imports resolver")
}
dir, _ := path.Split(filepath)
dir, _ := path.Split(fpath)
c.SetImportsResolver(&WorkingDirectoryResolver{
dir,
})

View file

@ -1,8 +1,8 @@
package core
import (
"errors"
"fmt"
"log"
"strings"
)
@ -12,8 +12,9 @@ type Compiler struct {
scope Pos
imports []string
importStack *Stack[string]
fileStack *Stack[string]
resolver ImportsResolver
source []rune
Warnings []CompilerError
@ -35,6 +36,7 @@ type CompilerError struct {
Description string
Causer Node
Source []rune
Trace []string
}
func (e CompilerError) Error() string {
@ -101,6 +103,14 @@ func (e CompilerError) Format() string {
lineStart = lineEnd
line++
}
b.WriteString("\nsource trace:")
// print import stack trace
for i := len(e.Trace) - 1; i >= 0; i-- {
p := e.Trace[i]
b.WriteString(fmt.Sprintf("\n[%d] %s", i+1, p))
}
return b.String()
}
@ -146,13 +156,22 @@ func (c *Compiler) addConstant(value Value) {
}
func (c *Compiler) Compile(p *Program) error {
c.fileStack.Push(p.Path)
defer c.fileStack.Pop()
for _, i := range p.Imports {
if err := c.resolveImport(i); err != nil {
return err
}
}
return c.compile(p.Block)
for _, s := range p.Block.statements {
if err := c.compile(s); err != nil {
return err
}
}
return nil
}
func (c *Compiler) compile(tree Node) error {
@ -784,7 +803,6 @@ func (c *Compiler) affirmReturnSignature(tree Node, sig TypeSignature) error {
return err
}
log.Printf("try affirming %s matches %s", v, sig)
if !sig.Matches(v) {
return c.error(fmt.Sprintf("function cannot return a value with type %s. defined to be %s", v, sig), n.value)
}
@ -1094,6 +1112,7 @@ func (c *Compiler) error(msg string, causer Node) CompilerError {
msg,
causer,
c.source,
c.fileStack.items[0:c.fileStack.Current],
}
}
@ -1109,6 +1128,13 @@ func (c *Compiler) resolveImport(path string) error {
}
}
// stop recursive imports
for i := c.fileStack.Current - 1; i >= 0; i-- {
if c.resolver.IsSame(path, c.fileStack.items[i]) {
return errors.New("recursive imports")
}
}
src, err := c.resolver.Resolve(path)
if err != nil {
return err
@ -1121,24 +1147,19 @@ func (c *Compiler) resolveImport(path string) error {
}
parser := NewParser(src, tokens)
p, err := parser.Parse()
p, err := parser.Parse(path)
if err != nil {
return err
}
oldChunk := c.Chunk
oldSrc := c.source
c.Chunk = NewChunk([]Bytecode{}, []Value{})
// update source for more descriptive errors
c.source = []rune(src)
if err := c.Compile(p); err != nil {
return err
}
c.imports[path] = c.Chunk
c.Chunk = oldChunk
c.source = oldSrc
return nil

View file

@ -87,6 +87,7 @@ func NewParser(source string, tokens []Token) *Parser {
type Program struct {
Imports []string
Block *BlockNode
Path string
}
func (p *Program) String() string {
@ -104,7 +105,7 @@ func (p *Program) String() string {
return builder.String()
}
func (p *Parser) Parse() (*Program, error) {
func (p *Parser) Parse(path string) (*Program, error) {
imports := make([]string, 0)
// top level statements
@ -138,6 +139,7 @@ func (p *Parser) Parse() (*Program, error) {
0,
p.curr.Start + p.curr.Length,
},
path,
}, nil
}