fix type-to-string conv. + fix binary type check + add modulo + rework import (now include)
Some checks failed
/ test (push) Failing after 41s
Some checks failed
/ test (push) Failing after 41s
This commit is contained in:
parent
91baf28fdf
commit
575fd8e37a
7 changed files with 131 additions and 91 deletions
|
|
@ -173,28 +173,10 @@ func (c *Compiler) addConstant(value Value) {
|
|||
c.add(Bytecode(len(chunk.Constants) - 1))
|
||||
}
|
||||
|
||||
func (c *Compiler) Compile(p *Program) error {
|
||||
func (c *Compiler) Compile(p *Program) (TypeSignature, error) {
|
||||
c.fileStack.Push(p.Path)
|
||||
|
||||
for _, i := range p.Imports {
|
||||
if err := c.resolveImport(i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for i, s := range p.Block.statements {
|
||||
if _, err := c.compile(s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i != len(p.Block.statements)-1 {
|
||||
c.add(InstructionPop)
|
||||
}
|
||||
}
|
||||
|
||||
c.fileStack.Pop()
|
||||
|
||||
return nil
|
||||
return c.compile(p.Block)
|
||||
}
|
||||
|
||||
func EscapeString(in string) string {
|
||||
|
|
@ -682,6 +664,9 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
|||
|
||||
return sig, nil
|
||||
|
||||
case IncludeNodeType:
|
||||
return c.compileInclude(tree.(*IncludeNode))
|
||||
|
||||
case AccessNodeType:
|
||||
n := tree.(*AccessNode)
|
||||
ps, err := c.compile(n.source)
|
||||
|
|
@ -837,20 +822,33 @@ func (c *Compiler) compileBinary(binary *BinaryNode) (TypeSignature, error) {
|
|||
case BinarySubtraction:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionSubFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionSubInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot subtract %s", tl), binary.operator)
|
||||
}
|
||||
case BinaryMultiplication:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionMulFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionMulInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot multiply %s", tl), binary.operator)
|
||||
}
|
||||
case BinaryDivision:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionDivFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionDivInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot divide %s", tl), binary.operator)
|
||||
}
|
||||
|
||||
case BinaryModulo:
|
||||
if tl.Type() == TypeInteger {
|
||||
c.add(InstructionModInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot compute modulo of %s", tl), binary.operator)
|
||||
}
|
||||
case BinaryEquality:
|
||||
c.add(InstructionEquals)
|
||||
|
|
@ -862,36 +860,52 @@ func (c *Compiler) compileBinary(binary *BinaryNode) (TypeSignature, error) {
|
|||
case BinaryLess:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionLessFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionLessInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot compare ordering of %s", tl), binary.operator)
|
||||
}
|
||||
res = &BooleanSignature{}
|
||||
case BinaryGreater:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionGreaterFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionGreaterInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot compare ordering of %s", tl), binary.operator)
|
||||
}
|
||||
res = &BooleanSignature{}
|
||||
case BinaryLessEqual:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionLessOrEqualFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionLessOrEqualInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot compare ordering of %s", tl), binary.operator)
|
||||
}
|
||||
res = &BooleanSignature{}
|
||||
case BinaryGreaterEqual:
|
||||
if tl.Type() == TypeFloat {
|
||||
c.add(InstructionGreaterOrEqualFloat)
|
||||
} else {
|
||||
} else if tl.Type() == TypeInteger {
|
||||
c.add(InstructionGreaterOrEqualInt)
|
||||
} else {
|
||||
return nil, c.error(fmt.Sprintf("cannot compare ordering of %s", tl), binary.operator)
|
||||
}
|
||||
res = &BooleanSignature{}
|
||||
|
||||
case BinaryBooleanAnd:
|
||||
if tl.Type() != TypeBoolean {
|
||||
return nil, c.error(fmt.Sprintf("cannot boolean-and of non-boolean %s", tl), binary.operator)
|
||||
}
|
||||
|
||||
c.add(InstructionAnd)
|
||||
res = &BooleanSignature{}
|
||||
case BinaryBooleanOr:
|
||||
if tl.Type() != TypeBoolean {
|
||||
return nil, c.error(fmt.Sprintf("cannot boolean-or of non-boolean %s", tl), binary.operator)
|
||||
}
|
||||
|
||||
c.add(InstructionOr)
|
||||
res = &BooleanSignature{}
|
||||
}
|
||||
|
|
@ -1071,49 +1085,50 @@ func (c *Compiler) warn(msg string, causer Node) {
|
|||
c.Warnings = append(c.Warnings, c.error(msg, causer))
|
||||
}
|
||||
|
||||
func (c *Compiler) resolveImport(imp Import) error {
|
||||
res, err := c.resolver.Resolve(c.fileStack.Peek(), imp.path)
|
||||
func (c *Compiler) compileInclude(include *IncludeNode) (TypeSignature, error) {
|
||||
res, err := c.resolver.Resolve(c.fileStack.Peek(), include.path.value)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if already imported and available
|
||||
// warn if already included
|
||||
for _, i := range c.imports {
|
||||
if c.resolver.IsSame(res.Path, i) {
|
||||
return nil
|
||||
c.warn("already included elsewhere", include)
|
||||
}
|
||||
}
|
||||
|
||||
// stop recursive imports
|
||||
// stop recursive includes
|
||||
for i := c.fileStack.Current - 1; i >= 0; i-- {
|
||||
if c.resolver.IsSame(res.Path, c.fileStack.items[i]) {
|
||||
return c.error("recursive import", imp)
|
||||
return nil, c.error("recursive inclusion", include)
|
||||
}
|
||||
}
|
||||
|
||||
l := NewLexer(res.Source)
|
||||
tokens, err := l.Tokenize()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parser := NewParser(res.Source, append(c.fileStack.Slice(), res.Path), tokens)
|
||||
p, err := parser.Parse(res.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oldSrc := c.source
|
||||
|
||||
// update source for more descriptive errors
|
||||
c.source = []rune(res.Source)
|
||||
if err := c.Compile(p); err != nil {
|
||||
return err
|
||||
t, err := c.Compile(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.source = oldSrc
|
||||
|
||||
return nil
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (c *Compiler) SetImportsResolver(resolver ImportsResolver) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue