Skip to content

Commit

Permalink
Detect inputs and outputs for inline assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
Kestred committed Feb 25, 2016
1 parent 9e3b5e3 commit 9df0b3a
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 114 deletions.
43 changes: 22 additions & 21 deletions code/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,14 @@ type Evaluable interface {
}

func (b *Block) ImplementsEvaluable() {}
func (s *InlineAsm) ImplementsEvaluable() {}
func (s *AsmBlock) ImplementsEvaluable() {}
func (d *ImmutableDecl) ImplementsEvaluable() {}
func (d *MutableDecl) ImplementsEvaluable() {}
func (s *IfStmt) ImplementsEvaluable() {}
func (s *WhileStmt) ImplementsEvaluable() {}
func (s *ForStmt) ImplementsEvaluable() {}
func (s *EvalStmt) ImplementsEvaluable() {}
func (s *AssignStmt) ImplementsEvaluable() {}
func (s *SyscallStmt) ImplementsEvaluable() {}
func (s *ReturnStmt) ImplementsEvaluable() {}
func (s *DoneStmt) ImplementsEvaluable() {}

Expand Down Expand Up @@ -132,14 +131,13 @@ type Stmt interface {
ImplementsStmt()
}

func (s *IfStmt) ImplementsStmt() {}
func (s *WhileStmt) ImplementsStmt() {}
func (s *ForStmt) ImplementsStmt() {}
func (s *EvalStmt) ImplementsStmt() {}
func (s *AssignStmt) ImplementsStmt() {}
func (s *SyscallStmt) ImplementsStmt() {}
func (s *ReturnStmt) ImplementsStmt() {}
func (s *DoneStmt) ImplementsStmt() {}
func (s *IfStmt) ImplementsStmt() {}
func (s *WhileStmt) ImplementsStmt() {}
func (s *ForStmt) ImplementsStmt() {}
func (s *EvalStmt) ImplementsStmt() {}
func (s *AssignStmt) ImplementsStmt() {}
func (s *ReturnStmt) ImplementsStmt() {}
func (s *DoneStmt) ImplementsStmt() {}

type Expr interface {
Node
Expand Down Expand Up @@ -228,13 +226,24 @@ func Blok(nodes []Evaluable) *Block {
return &Block{Nodes: nodes}
}

type InlineAsm struct {
type AsmBlock struct {
NodeBase

// syntax
Source string

// semantics
Inputs []AsmBinding
Outputs []AsmBinding
}

func Asm(source string) *InlineAsm {
return &InlineAsm{Source: source}
type AsmBinding struct {
Name *Identifier
Offset int
}

func Asm(source string) *AsmBlock {
return &AsmBlock{Source: source}
}

// A declaration is represented by one of the following
Expand Down Expand Up @@ -426,14 +435,6 @@ type (
Expr Expr
}

SyscallStmt struct {
NodeBase

// syntax
Number Expr
Arguments [6]Expr
}

ReturnStmt struct {
NodeBase

Expand Down
53 changes: 26 additions & 27 deletions code/code/section.go → code/ast/section.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package code
package ast

import (
"github.com/kestred/philomath/code/ast"
"github.com/kestred/philomath/code/utils"
)
import "github.com/kestred/philomath/code/utils"

type Section struct {
Root ast.Node
Nodes []ast.Node
Root Node
Nodes []Node
Parent *Section
Progress int
}

func PrepareTree(root ast.Node, parent *Section) Section {
func FlattenTree(root Node, parent *Section) Section {
// TODO: get parentNode properly
var top ast.Node = nil
var top Node = nil
if parent != nil {
top = parent.Root
}
Expand All @@ -23,36 +20,38 @@ func PrepareTree(root ast.Node, parent *Section) Section {
return Section{Root: root, Nodes: nodes, Parent: parent}
}

func flattenTree(node ast.Node, parent ast.Node) []ast.Node {
func flattenTree(node Node, parent Node) []Node {
node.SetParent(parent)
nodes := []ast.Node{node}
nodes := []Node{node}
switch n := node.(type) {
case *ast.TopScope:
case *TopScope:
for _, decl := range n.Decls {
nodes = append(nodes, flattenTree(decl, n)...)
}
case *ast.Block:
case *Block:
for _, subnode := range n.Nodes {
nodes = append(nodes, flattenTree(subnode, n)...)
}
case *AsmBlock:
break // nothing to add

// declarations
case *ast.ImmutableDecl:
case *ImmutableDecl:
nodes = append(nodes, n.Name)
nodes = append(nodes, flattenTree(n.Defn, n)...)
case *ast.MutableDecl:
case *MutableDecl:
nodes = append(nodes, n.Name)
nodes = append(nodes, flattenTree(n.Type, n)...)
nodes = append(nodes, flattenTree(n.Expr, n)...)

// definitions
case *ast.ConstantDefn:
case *ConstantDefn:
nodes = append(nodes, flattenTree(n.Expr, n)...)

// statements
case *ast.EvalStmt:
case *EvalStmt:
nodes = append(nodes, flattenTree(n.Expr, n)...)
case *ast.AssignStmt:
case *AssignStmt:
for _, expr := range n.Left {
nodes = append(nodes, flattenTree(expr, n)...)
}
Expand All @@ -61,30 +60,30 @@ func flattenTree(node ast.Node, parent ast.Node) []ast.Node {
}

// expressions
case *ast.PostfixExpr:
case *PostfixExpr:
nodes = append(nodes, flattenTree(n.Subexpr, n)...)
nodes = append(nodes, n.Operator)
case *ast.InfixExpr:
case *InfixExpr:
nodes = append(nodes, flattenTree(n.Left, n)...)
nodes = append(nodes, n.Operator)
nodes = append(nodes, flattenTree(n.Right, n)...)
case *ast.PrefixExpr:
case *PrefixExpr:
nodes = append(nodes, n.Operator)
nodes = append(nodes, flattenTree(n.Subexpr, n)...)
case *ast.GroupExpr:
case *GroupExpr:
nodes = append(nodes, flattenTree(n.Subexpr, n)...)
case *ast.ProcedureExpr:
case *ProcedureExpr:
nodes = append(nodes, n.Return)
nodes = append(nodes, flattenTree(n.Block, n)...)

// literals
case *ast.Identifier,
*ast.NumberLiteral,
*ast.TextLiteral:
case *Identifier,
*NumberLiteral,
*TextLiteral:
break // nothing to add

// types
case *ast.BaseType:
case *BaseType:
break // nothing to add

default:
Expand Down
99 changes: 50 additions & 49 deletions code/code/section_test.go → code/ast/section_test.go
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
package code
package ast

/*
import (
"reflect"
"testing"
"github.com/kestred/philomath/code/ast"
"github.com/kestred/philomath/code/parser"
"github.com/stretchr/testify/assert"
)
func parseExample(t *testing.T, input string) ast.Node {
func parseExample(t *testing.T, input string) Node {
p := parser.Make("example", false, []byte(input))
node := p.ParseEvaluable()
assert.Empty(t, p.Errors, "Unexpected parser errors")
return node
}
func TestFlattenBlock(t *testing.T) {
expected := []ast.Node{
&ast.Block{},
expected := []Node{
&Block{},
// foo := -3;
&ast.MutableDecl{},
&ast.Identifier{},
&ast.BaseType{},
&ast.PrefixExpr{},
&ast.OperatorDefn{},
&ast.NumberLiteral{},
&MutableDecl{},
&Identifier{},
&BaseType{},
&PrefixExpr{},
&OperatorDefn{},
&NumberLiteral{},
// baz :: 1;
&ast.ImmutableDecl{},
&ast.Identifier{},
&ast.ConstantDefn{},
&ast.NumberLiteral{},
&ImmutableDecl{},
&Identifier{},
&ConstantDefn{},
&NumberLiteral{},
// (2 + foo) + baz;
&ast.EvalStmt{},
&ast.InfixExpr{},
&ast.GroupExpr{},
&ast.InfixExpr{},
&ast.NumberLiteral{},
&ast.OperatorDefn{},
&ast.Identifier{},
&ast.OperatorDefn{},
&ast.Identifier{},
&EvalStmt{},
&InfixExpr{},
&GroupExpr{},
&InfixExpr{},
&NumberLiteral{},
&OperatorDefn{},
&Identifier{},
&OperatorDefn{},
&Identifier{},
// {
&ast.Block{},
&Block{},
// bar := foo;
&ast.MutableDecl{},
&ast.Identifier{},
&ast.BaseType{},
&ast.Identifier{},
&MutableDecl{},
&Identifier{},
&BaseType{},
&Identifier{},
// 0755 - baz;
&ast.EvalStmt{},
&ast.InfixExpr{},
&ast.NumberLiteral{},
&ast.OperatorDefn{},
&ast.Identifier{},
&EvalStmt{},
&InfixExpr{},
&NumberLiteral{},
&OperatorDefn{},
&Identifier{},
// foo = baz * 4;
&ast.AssignStmt{},
&ast.Identifier{},
&ast.InfixExpr{},
&ast.Identifier{},
&ast.OperatorDefn{},
&ast.NumberLiteral{},
&AssignStmt{},
&Identifier{},
&InfixExpr{},
&Identifier{},
&OperatorDefn{},
&NumberLiteral{},
// bar, foo = foo + 27, bar;
&ast.AssignStmt{},
&ast.Identifier{},
&ast.Identifier{},
&ast.InfixExpr{},
&ast.Identifier{},
&ast.OperatorDefn{},
&ast.NumberLiteral{},
&ast.Identifier{},
&AssignStmt{},
&Identifier{},
&Identifier{},
&InfixExpr{},
&Identifier{},
&OperatorDefn{},
&NumberLiteral{},
&Identifier{},
// }
}
Expand All @@ -88,7 +88,7 @@ func TestFlattenBlock(t *testing.T) {
}
}`)
section := PrepareTree(block, nil)
section := FlattenTree(block, nil)
assert.Equal(t, block, section.Root)
assert.Equal(t, block, section.Nodes[0])
for i, example := range expected {
Expand All @@ -104,3 +104,4 @@ func TestFlattenBlock(t *testing.T) {
}
}
}
*/
4 changes: 2 additions & 2 deletions code/bytecode/bytecode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"

// TODO: Maybe don't rely on parser et. al. when more code is stable
"github.com/kestred/philomath/code/code"
"github.com/kestred/philomath/code/ast"
"github.com/kestred/philomath/code/parser"
"github.com/kestred/philomath/code/semantics"
"github.com/stretchr/testify/assert"
Expand All @@ -14,7 +14,7 @@ func generateBytecode(t *testing.T, input string) *Program {
p := parser.Make("example", false, []byte(input))
node := p.ParseEvaluable()
assert.Empty(t, p.Errors, "Unexpected parser errors")
section := code.PrepareTree(node, nil)
section := ast.FlattenTree(node, nil)
semantics.ResolveNames(&section)
semantics.InferTypes(&section)
program := NewProgram()
Expand Down
4 changes: 2 additions & 2 deletions code/interpreter/interpreter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package interpreter
import (
"testing"

"github.com/kestred/philomath/code/ast"
"github.com/kestred/philomath/code/bytecode"
"github.com/kestred/philomath/code/code"
"github.com/kestred/philomath/code/parser"
"github.com/kestred/philomath/code/semantics"
"github.com/stretchr/testify/assert"
Expand All @@ -14,7 +14,7 @@ func evalExample(t *testing.T, input string) bytecode.Data {
p := parser.Make("example", false, []byte(input))
node := p.ParseEvaluable()
assert.Empty(t, p.Errors, "Unexpected parser errors")
section := code.PrepareTree(node, nil)
section := ast.FlattenTree(node, nil)
semantics.ResolveNames(&section)
semantics.InferTypes(&section)
program := bytecode.NewProgram()
Expand Down
Loading

0 comments on commit 9df0b3a

Please sign in to comment.