Skip to content

Commit

Permalink
clock support
Browse files Browse the repository at this point in the history
  • Loading branch information
mbellotti committed Apr 26, 2023
1 parent be604ed commit 2ed164b
Show file tree
Hide file tree
Showing 10 changed files with 377 additions and 196 deletions.
6 changes: 4 additions & 2 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,9 @@ func (i *Identifier) operandNode() {}
func (i *Identifier) expressionNode() {}
func (i *Identifier) TokenLiteral() string { return i.Token.Literal }
func (i *Identifier) Position() []int { return i.Token.GetPosition() }
func (i *Identifier) String() string { return i.Value }
func (i *Identifier) String() string {
return i.Value
}
func (i *Identifier) Type() string {
t := i.InferredType
if t != nil {
Expand Down Expand Up @@ -1094,7 +1096,7 @@ type Clock struct {
func (c *Clock) expressionNode() {}
func (c *Clock) TokenLiteral() string { return c.Token.Literal }
func (c *Clock) Position() []int { return c.Token.GetPosition() }
func (c *Clock) String() string { return c.Token.Literal }
func (c *Clock) String() string { return "now" }
func (c *Clock) Type() string {
t := c.InferredType
if t != nil {
Expand Down
2 changes: 1 addition & 1 deletion ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func TestString(t *testing.T) {
want = "foo.bar"
case *Clock:
got = t.String()
want = "test"
want = "now"
case *Nil:
got = t.String()
want = "test"
Expand Down
91 changes: 3 additions & 88 deletions llvm/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,8 @@ func (c *Compiler) compileParameterCall(pc *ast.ParameterCall) value.Value {
var err error
id := c.AliasToBaseRaw(pc.RawId())
spec := c.specStructs[id[0]]
ty, _ := spec.GetStructType(id[0:2]) //Removing the key
st := id[len(id)-2] //The struct is the second to last item
ty, _ := spec.GetStructType(id) //Removing the key
st := strings.Join(id[1:len(id)-1], "_") //The struct
key := id[len(id)-1]

var branches map[string]ast.Node
Expand Down Expand Up @@ -1591,7 +1591,7 @@ func negate(e ast.Expression) ast.Expression {
n.Left = negate(n.Left)
n.Right = negate(n.Right)

node := evaluate(n) // If Int/Float, evaluate and return the value
node := util.Evaluate(n) // If Int/Float, evaluate and return the value
return node
case *ast.Boolean:
if n.Value {
Expand Down Expand Up @@ -1624,91 +1624,6 @@ func negateTemporal(op string, n int) (string, int) {
return op2, n2
}

func evaluate(n *ast.InfixExpression) ast.Expression {
if util.IsCompare(n.Operator) {
return n
}
f1, ok1 := n.Left.(*ast.FloatLiteral)
i1, ok2 := n.Left.(*ast.IntegerLiteral)

if !ok1 && !ok2 {
return n
}

f2, ok1 := n.Right.(*ast.FloatLiteral)
i2, ok2 := n.Right.(*ast.IntegerLiteral)

if !ok1 && !ok2 {
return n
}

if f1 != nil {
if f2 != nil {
v := evalFloat(f1.Value, f2.Value, n.Operator)
return &ast.FloatLiteral{
Token: n.Token,
Value: v,
}
} else {
v := evalFloat(f1.Value, float64(i2.Value), n.Operator)
return &ast.FloatLiteral{
Token: n.Token,
Value: v,
}
}
} else {
if f2 != nil {
v := evalFloat(float64(i1.Value), f2.Value, n.Operator)
return &ast.FloatLiteral{
Token: n.Token,
Value: v,
}
} else {
if n.Operator == "/" {
//Return a float in the case of division
v := evalFloat(float64(i1.Value), float64(i2.Value), n.Operator)
return &ast.FloatLiteral{
Token: n.Token,
Value: v,
}
}
v := evalInt(i1.Value, i2.Value, n.Operator)
return &ast.IntegerLiteral{
Token: n.Token,
Value: v,
}
}
}
}

func evalFloat(f1 float64, f2 float64, op string) float64 {
switch op {
case "+":
return f1 + f2
case "-":
return f1 - f2
case "*":
return f1 * f2
case "/":
return f1 / f2
default:
panic(fmt.Sprintf("unsupported operator %s", op))
}
}

func evalInt(i1 int64, i2 int64, op string) int64 {
switch op {
case "+":
return i1 + i2
case "-":
return i1 - i2
case "*":
return i1 * i2
default:
panic(fmt.Sprintf("unsupported operator %s", op))
}
}

func (c *Compiler) GetIR() string {
return c.module.String()
}
Expand Down
60 changes: 0 additions & 60 deletions llvm/llvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,66 +418,6 @@ func TestNegate(t *testing.T) {
}
}

func TestEval(t *testing.T) {
tests := []*ast.InfixExpression{{
Left: &ast.IntegerLiteral{Value: 2},
Right: &ast.IntegerLiteral{Value: 2},
},
{
Left: &ast.FloatLiteral{Value: 2.5},
Right: &ast.IntegerLiteral{Value: 2},
},
{
Left: &ast.IntegerLiteral{Value: 2},
Operator: "+",
Right: &ast.FloatLiteral{Value: 2.5},
}}

operators := []string{"+", "-", "/", "*"}

results := []ast.Node{
&ast.IntegerLiteral{Value: 4},
&ast.FloatLiteral{Value: 4.5},
&ast.FloatLiteral{Value: 4.5},
&ast.IntegerLiteral{Value: 0},
&ast.FloatLiteral{Value: .5},
&ast.FloatLiteral{Value: -.5},
&ast.FloatLiteral{Value: 1},
&ast.FloatLiteral{Value: 1.25},
&ast.FloatLiteral{Value: .8},
&ast.IntegerLiteral{Value: 4},
&ast.FloatLiteral{Value: 5},
&ast.FloatLiteral{Value: 5},
}

i := 0
for _, o := range operators {
for _, n := range tests {
n.Operator = o
test := evaluate(n)
switch actual := test.(type) {
case *ast.IntegerLiteral:
expected, ok := results[i].(*ast.IntegerLiteral)
if !ok {
t.Fatalf("expected value a different type from actual expected=%s actual=%s", results[i], test)
}
if expected.Value != actual.Value {
t.Fatalf("expected value a different from actual expected=%s actual=%s", expected, actual)
}
case *ast.FloatLiteral:
expected, ok := results[i].(*ast.FloatLiteral)
if !ok {
t.Fatalf("expected value a different type from actual expected=%s actual=%s", results[i], test)
}
if expected.Value != actual.Value {
t.Fatalf("expected value a different from actual expected=%s actual=%s", expected, actual)
}
}
i++
}
}
}

func TestIsVarSet(t *testing.T) {
c := NewCompiler()
c.specStructs["test"] = preprocess.NewSpecRecord()
Expand Down
34 changes: 0 additions & 34 deletions llvm/llvm_xmisc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,6 @@ func TestNegateTemporal(t *testing.T) {
}
}

func TestEvalFloat(t *testing.T) {
test1 := evalFloat(2.1, 1.5, "+")
if test1 != 3.6 {
t.Fatal("evalFloat failed to eval + correctly")
}
test2 := evalFloat(2.5, 1.5, "-")
if test2 != 1 {
t.Fatal("evalFloat failed to eval - correctly")
}
test3 := evalFloat(2.1, 1.0, "*")
if test3 != 2.1 {
t.Fatal("evalFloat failed to eval * correctly")
}
test4 := evalFloat(2.0, 2.0, "/")
if test4 != 1.0 {
t.Fatal("evalFloat failed to eval / correctly")
}
}

func TestEvalInt(t *testing.T) {
test1 := evalInt(2, 1, "+")
if test1 != 3 {
t.Fatal("evalInt failed to eval + correctly")
}
test2 := evalInt(2, 1, "-")
if test2 != 1 {
t.Fatal("evalInt failed to eval - correctly")
}
test3 := evalInt(2, 1, "*")
if test3 != 2 {
t.Fatal("evalInt failed to eval * correctly")
}
}

func TestValidOperator(t *testing.T) {
c := NewCompiler()
boolTy := &ast.Type{Type: "BOOL"}
Expand Down
64 changes: 62 additions & 2 deletions preprocess/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,56 @@ func (p *Processor) attachElif(n *ast.IfExpression, el *ast.IfExpression) *ast.I
return n
}

func (p *Processor) formatIndex(n *ast.InfixExpression) string {
_, okR := n.Right.(*ast.Clock)
_, okL := n.Left.(*ast.Clock)

if okR && n.Operator == "-" {
panic("negative indexes not possible")
}

if (okR || okL) && n.Operator == "+" {
panic("index out of range")
}

if (okR || okL) && n.Operator == "*" {
panic("index out of range")
}

// If left and right are numeric it will evaluate
// and return new node, otherwise just returns the
// same node
val := util.Evaluate(n)
if _, okF := val.(*ast.FloatLiteral); okF {
panic("index must be a whole number")
}

if _, ok := val.(*ast.InfixExpression); !ok {
return val.String()
}

var left, right string
inf := val.(*ast.InfixExpression)
switch l := inf.Left.(type) {
case *ast.IntegerLiteral:
left = l.String()
case *ast.Clock:
left = l.String()
case ast.Nameable:
left = l.IdString()
}

switch r := inf.Right.(type) {
case *ast.IntegerLiteral:
right = r.String()
case *ast.Clock:
right = r.String()
case ast.Nameable:
right = r.IdString()
}
return fmt.Sprintf("(%s %s %s)", left, inf.Operator, right)
}

func (p *Processor) walk(n ast.Node) (ast.Node, error) {
var err error
var pro ast.Node
Expand Down Expand Up @@ -517,8 +567,18 @@ func (p *Processor) walk(n ast.Node) (ast.Node, error) {
return node, err
}
node.Left = l.(ast.Expression)
rawid := l.(ast.Nameable).RawId()
rawid = append(rawid, node.Index.String())
var rawid []string
switch ex := node.Index.(type) {
case *ast.InfixExpression:
rawid = node.Left.(ast.Nameable).RawId()
idx := p.formatIndex(ex)
rawid = append(rawid, idx)
case *ast.IntegerLiteral:
rawid = node.Left.(ast.Nameable).RawId()
rawid = append(rawid, node.Index.String())
default:
panic("unsupported syntax for index")
}
node.ProcessedName = rawid
return node, err

Expand Down

0 comments on commit 2ed164b

Please sign in to comment.