Fix parser edge-cases, fix wasm, refactor
This commit is contained in:
parent
c364e09fc9
commit
be7809d467
5 changed files with 38 additions and 25 deletions
|
|
@ -130,13 +130,13 @@ func TestAll(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Log("Initializing parser")
|
t.Log("Initializing parser")
|
||||||
p := NewParser(tokens)
|
p := NewParser(tc.src, tokens)
|
||||||
|
|
||||||
t.Log("Parsing tokens")
|
t.Log("Parsing tokens")
|
||||||
tree, err := p.Parse()
|
tree, err := p.Parse(tc.src)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
print(err.(ParsingError).Format([]rune(tc.src)))
|
print(err.(ParsingError).Format())
|
||||||
t.Fatalf("parser had an error")
|
t.Fatalf("parser had an error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ func TestAll(t *testing.T) {
|
||||||
c := NewCompiler([]rune(tc.src))
|
c := NewCompiler([]rune(tc.src))
|
||||||
|
|
||||||
t.Log("Compiling parse tree")
|
t.Log("Compiling parse tree")
|
||||||
err = c.compile(tree)
|
err = c.Compile(tree)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Compiler had an error: %s", err)
|
t.Fatalf("Compiler had an error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
@ -173,11 +173,11 @@ func BenchmarkAll(b *testing.B) {
|
||||||
l := NewLexer(tc.src)
|
l := NewLexer(tc.src)
|
||||||
tokens, _ := l.Tokenize()
|
tokens, _ := l.Tokenize()
|
||||||
|
|
||||||
p := NewParser(tokens)
|
p := NewParser(tc.src, tokens)
|
||||||
tree, _ := p.Parse()
|
tree, _ := p.Parse(tc.src)
|
||||||
|
|
||||||
c := NewCompiler([]rune(tc.src))
|
c := NewCompiler([]rune(tc.src))
|
||||||
_ = c.compile(tree)
|
_ = c.Compile(tree)
|
||||||
|
|
||||||
vm := NewVM(c.Chunk, 256, 256)
|
vm := NewVM(c.Chunk, 256, 256)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ func (c *Compiler) compile(tree Node) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ReferenceNodeType:
|
case ReferenceNodeType:
|
||||||
c.getVar(tree.(*ReferenceNode).name)
|
c.addGetVar(tree.(*ReferenceNode).name)
|
||||||
|
|
||||||
case BinaryNodeType:
|
case BinaryNodeType:
|
||||||
err := c.compileBinary(tree.(*BinaryNode))
|
err := c.compileBinary(tree.(*BinaryNode))
|
||||||
|
|
@ -275,7 +275,7 @@ func (c *Compiler) compile(tree Node) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if sig.Type() != TypeBoolean {
|
if sig.Type() != TypeBoolean {
|
||||||
return c.error(fmt.Sprintf("condition cannot give non-boolean type %s", sig), n.condition)
|
return c.error(fmt.Sprintf("conditional requires boolean; cannot use non-boolean type %s", sig), n.condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the stack should have whether the condition was truthful
|
// the stack should have whether the condition was truthful
|
||||||
|
|
@ -365,7 +365,7 @@ func (c *Compiler) compile(tree Node) error {
|
||||||
return c.error(fmt.Sprintf("%s is already declared in this scope", n.name), n)
|
return c.error(fmt.Sprintf("%s is already declared in this scope", n.name), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.setVar(n.name, n.value, n.declare)
|
err := c.addSetVar(n.name, n.value, n.declare)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +871,7 @@ func (c *Compiler) isVarDeclaredHere(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) getVar(name string) {
|
func (c *Compiler) addGetVar(name string) {
|
||||||
if c.isGlobal(name) {
|
if c.isGlobal(name) {
|
||||||
c.add(InstructionGetGlobal)
|
c.add(InstructionGetGlobal)
|
||||||
c.addConstant(&StringValue{
|
c.addConstant(&StringValue{
|
||||||
|
|
@ -885,7 +885,7 @@ func (c *Compiler) getVar(name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) setVar(name string, value Node, declare bool) error {
|
func (c *Compiler) addSetVar(name string, value Node, declare bool) error {
|
||||||
err := c.compile(value)
|
err := c.compile(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,10 @@ func (p *Parser) Parse(path string) (*Program, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b != nil {
|
||||||
statements = append(statements, b)
|
statements = append(statements, b)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &Program{
|
return &Program{
|
||||||
imports,
|
imports,
|
||||||
|
|
@ -774,16 +776,23 @@ func (p *Parser) statement() (Node, error) {
|
||||||
|
|
||||||
return &BreakpointNode{}, nil
|
return &BreakpointNode{}, nil
|
||||||
|
|
||||||
|
case TokenImport:
|
||||||
|
defer p.advance()
|
||||||
|
return nil, p.error("import statements must be top-level", p.curr)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err := p.error("invalid statement", p.curr)
|
defer p.advance()
|
||||||
p.advance()
|
return nil, p.error("invalid statement", p.curr)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) block(canBeStatement bool) (Node, error) {
|
func (p *Parser) block(canBeStatement bool) (Node, error) {
|
||||||
if canBeStatement {
|
if canBeStatement {
|
||||||
if !p.accept(TokenOpenBrace) {
|
if !p.accept(TokenOpenBrace) {
|
||||||
|
if p.curr.Type == TokenEOF {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
return p.statement()
|
return p.statement()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
func TestNewParser(t *testing.T) {
|
func TestNewParser(t *testing.T) {
|
||||||
tokens := make([]Token, 0)
|
tokens := make([]Token, 0)
|
||||||
|
|
||||||
p := NewParser(tokens)
|
p := NewParser("", tokens)
|
||||||
|
|
||||||
if p == nil {
|
if p == nil {
|
||||||
t.Fatal("parser should not be nil")
|
t.Fatal("parser should not be nil")
|
||||||
|
|
@ -34,7 +34,7 @@ func TestNewParser(t *testing.T) {
|
||||||
func BenchmarkNewParser(b *testing.B) {
|
func BenchmarkNewParser(b *testing.B) {
|
||||||
tokens := make([]Token, 0)
|
tokens := make([]Token, 0)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = NewParser(tokens)
|
_ = NewParser("", tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,17 +908,17 @@ func TestParser_Parse(t *testing.T) {
|
||||||
|
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
t.Logf("Initializing parser")
|
t.Logf("Initializing parser")
|
||||||
p := NewParser(data.tokens)
|
p := NewParser("", data.tokens)
|
||||||
|
|
||||||
t.Logf("Parsing main")
|
t.Logf("Parsing main")
|
||||||
tree, err := p.Parse()
|
tree, err := p.Parse("")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error(s): %s", err.(ParsingError).Format([]rune(SerializeTokens(data.tokens))))
|
t.Fatalf("Unexpected error(s): %s", err.(ParsingError).Format())
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Checking parsed tree")
|
t.Logf("Checking parsed tree")
|
||||||
NodeEquality(t, tree, data.tree)
|
NodeEquality(t, tree.Block, data.tree)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -929,9 +929,9 @@ func BenchmarkParser_Parse(b *testing.B) {
|
||||||
for name, data := range tokenData {
|
for name, data := range tokenData {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
p := NewParser(data.tokens)
|
p := NewParser("", data.tokens)
|
||||||
|
|
||||||
_, _ = p.Parse()
|
_, _ = p.Parse("")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ type JsResolver struct {
|
||||||
jsResolver js.Value
|
jsResolver js.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *JsResolver) IsSame(a, b string) bool {
|
||||||
|
return a == b
|
||||||
|
}
|
||||||
|
|
||||||
func (r *JsResolver) Resolve(name string) (string, error) {
|
func (r *JsResolver) Resolve(name string) (string, error) {
|
||||||
jsv := r.jsResolver.Invoke(name)
|
jsv := r.jsResolver.Invoke(name)
|
||||||
|
|
||||||
|
|
@ -56,7 +60,7 @@ func run(_ js.Value, args []js.Value) interface{} {
|
||||||
|
|
||||||
parser := core.NewParser(source, tokens)
|
parser := core.NewParser(source, tokens)
|
||||||
|
|
||||||
tree, err := parser.Parse()
|
tree, err := parser.Parse(source)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var e core.FormatedError
|
var e core.FormatedError
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue