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 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 { if ctx.Debug {
log.Println("Reading file") log.Println("Reading file")
} }
f, err := os.ReadFile(filepath) f, err := os.ReadFile(fpath)
if err != nil { if err != nil {
return nil, err return nil, err
@ -83,7 +83,12 @@ func makeChunk(ctx *Context, filepath string, ignoreWarnings bool) (*core.Chunk,
log.Println("Initialized parser") 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 { if ctx.Debug {
log.Printf("Parsed tree, meaning:\n%s", tree) 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") log.Println("Setting imports resolver")
} }
dir, _ := path.Split(filepath) dir, _ := path.Split(fpath)
c.SetImportsResolver(&WorkingDirectoryResolver{ c.SetImportsResolver(&WorkingDirectoryResolver{
dir, dir,
}) })

View file

@ -1,8 +1,8 @@
package core package core
import ( import (
"errors"
"fmt" "fmt"
"log"
"strings" "strings"
) )
@ -12,8 +12,9 @@ type Compiler struct {
scope Pos scope Pos
imports []string imports []string
importStack *Stack[string] fileStack *Stack[string]
resolver ImportsResolver resolver ImportsResolver
source []rune source []rune
Warnings []CompilerError Warnings []CompilerError
@ -35,6 +36,7 @@ type CompilerError struct {
Description string Description string
Causer Node Causer Node
Source []rune Source []rune
Trace []string
} }
func (e CompilerError) Error() string { func (e CompilerError) Error() string {
@ -101,6 +103,14 @@ func (e CompilerError) Format() string {
lineStart = lineEnd lineStart = lineEnd
line++ 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() return b.String()
} }
@ -146,13 +156,22 @@ func (c *Compiler) addConstant(value Value) {
} }
func (c *Compiler) Compile(p *Program) error { func (c *Compiler) Compile(p *Program) error {
c.fileStack.Push(p.Path)
defer c.fileStack.Pop()
for _, i := range p.Imports { for _, i := range p.Imports {
if err := c.resolveImport(i); err != nil { if err := c.resolveImport(i); err != nil {
return err 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 { func (c *Compiler) compile(tree Node) error {
@ -784,7 +803,6 @@ func (c *Compiler) affirmReturnSignature(tree Node, sig TypeSignature) error {
return err return err
} }
log.Printf("try affirming %s matches %s", v, sig)
if !sig.Matches(v) { 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) 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, msg,
causer, causer,
c.source, 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) src, err := c.resolver.Resolve(path)
if err != nil { if err != nil {
return err return err
@ -1121,24 +1147,19 @@ func (c *Compiler) resolveImport(path string) error {
} }
parser := NewParser(src, tokens) parser := NewParser(src, tokens)
p, err := parser.Parse() p, err := parser.Parse(path)
if err != nil { if err != nil {
return err return err
} }
oldChunk := c.Chunk
oldSrc := c.source oldSrc := c.source
c.Chunk = NewChunk([]Bytecode{}, []Value{}) // update source for more descriptive errors
c.source = []rune(src) c.source = []rune(src)
if err := c.Compile(p); err != nil { if err := c.Compile(p); err != nil {
return err return err
} }
c.imports[path] = c.Chunk
c.Chunk = oldChunk
c.source = oldSrc c.source = oldSrc
return nil return nil

View file

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