Skip to content

Commit

Permalink
first pass at compound string rules
Browse files Browse the repository at this point in the history
  • Loading branch information
mbellotti committed Apr 30, 2023
1 parent 8704184 commit 86db50f
Show file tree
Hide file tree
Showing 18 changed files with 1,695 additions and 1,154 deletions.
9 changes: 9 additions & 0 deletions grammar/FaultParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ constSpec

stringDecl
: IDENT '=' string_ eos
| IDENT '=' compoundString eos
| IDENT '=' compoundString eos
;

compoundString
: operandName
| '!' operandName
| compoundString '&&' compoundString
| compoundString '||' compoundString
;

identList
Expand Down
42 changes: 38 additions & 4 deletions listener/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,37 @@ func (l *FaultListener) ExitFloat_(c *parser.Float_Context) {
})
}

func (l *FaultListener) ExitCompoundString(c *parser.CompoundStringContext) {
if c.GetChildCount() < 2 {
return //Single operand, no actions
}

if pre, ok := c.GetChild(0).(antlr.TerminalNode); ok && pre.GetText() == "!" {
token := util.GenerateToken("IDENT", "IDENT", c.GetStart(), c.GetStop())
exp := l.pop()
e := &ast.PrefixExpression{
Token: token,
Operator: "-",
Right: exp.(ast.Expression),
}
l.push(e)
return
}

operator := c.GetChild(1).(antlr.TerminalNode).GetText()
token := util.GenerateToken(string(ast.OPS[operator]), operator, c.GetStart(), c.GetStop())

rght := l.pop()
lft := l.pop()
e := &ast.InfixExpression{
Token: token,
Left: lft.(ast.Expression),
Operator: operator,
Right: rght.(ast.Expression),
}
l.push(e)
}

func (l *FaultListener) ExitStringDecl(c *parser.StringDeclContext) {
token := util.GenerateToken("GLOBAL", "GLOBAL", c.GetStart(), c.GetStop())

Expand All @@ -1229,12 +1260,15 @@ func (l *FaultListener) ExitStringDecl(c *parser.StringDeclContext) {
Value: c.IDENT().GetText(),
Spec: l.currSpec,
}

if _, ok := val.(*ast.StringLiteral); !ok {
switch val.(type) {
case *ast.StringLiteral:
l.push(&ast.DefStatement{Token: token, Name: ident, Value: val.(ast.Expression)})
case *ast.InfixExpression, *ast.PrefixExpression:
token2 := util.GenerateToken("COMPOUND_STRING", "COMPOUND_STRING", c.GetStart(), c.GetStop())
l.push(&ast.ExpressionStatement{Token: token, Expression: &ast.InfixExpression{Token: token2, Left: ident, Operator: "=", Right: val.(ast.Expression)}})
default:
panic(fmt.Sprintf("top of the stack is not a string got %T: line %d col %d", val, c.GetStart().GetLine(), c.GetStart().GetColumn()))
}

l.push(&ast.DefStatement{Token: token, Name: ident, Value: val.(ast.Expression)})
}

func (l *FaultListener) ExitString_(c *parser.String_Context) {
Expand Down
22 changes: 22 additions & 0 deletions llvm/alloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ func (c *Compiler) allocVariable(id []string, val value.Value, pos []int) {
alloc = c.contextBlock.NewAlloca(irtypes.I1)
alloc.SetName(name)
store = c.contextBlock.NewStore(v, alloc)
case *ir.InstAnd:
alloc = c.contextBlock.NewAlloca(irtypes.I1)
alloc.SetName(name)
if v.Type() == nil {
v.Typ = irtypes.I1
}
store = c.contextBlock.NewStore(v, alloc)
case *ir.InstOr:
alloc = c.contextBlock.NewAlloca(irtypes.I1)
alloc.SetName(name)
if v.Type() == nil {
v.Typ = irtypes.I1
}
store = c.contextBlock.NewStore(v, alloc)
case *ir.Func:
return
default:
Expand Down Expand Up @@ -115,6 +129,14 @@ func (c *Compiler) globalVariable(id []string, val value.Value, pos []int) {
case *ir.InstFCmp:
c.allocVariable(id, val, pos)
case *ir.Func:
case *ir.InstAnd:
placeholder := constant.NewAnd(constant.NewBool(false), constant.NewBool(false))
alloc := c.module.NewGlobalDef(name, placeholder)
c.storeGlobal(name, alloc)
case *ir.InstOr:
placeholder := constant.NewAnd(constant.NewBool(false), constant.NewBool(false))
alloc := c.module.NewGlobalDef(name, placeholder)
c.storeGlobal(name, alloc)
default:
panic(fmt.Sprintf("unknown variable type %T line: %d col: %d", v, pos[0], pos[1]))
}
Expand Down
108 changes: 46 additions & 62 deletions llvm/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ func (c *Compiler) compile(node ast.Node) {
}
case *ast.FunctionLiteral:

case *ast.ExpressionStatement:
c.compile(v.Expression)

case *ast.InfixExpression:
c.compileInfix(v)

Expand Down Expand Up @@ -700,7 +703,7 @@ func (c *Compiler) compileFunction(node ast.Node) value.Value {

func (c *Compiler) compileIndex(node *ast.IndexExpression) *ir.InstLoad {
var value value.Value
if node.Left.Type() == "BOOLEAN" {
if node.Left.Type() == "BOOL" {
value = constant.NewBool(false)
} else {
value = constant.NewFloat(irtypes.Double, float64(0.000000000009))
Expand Down Expand Up @@ -736,7 +739,15 @@ func (c *Compiler) compileInfix(node *ast.InfixExpression) value.Value {
if !c.validOperator(node, true) {
panic(fmt.Sprintf("operator %s cannot be used on variables of type %s and %s", node.Operator, node.Left.Type(), node.Right.Type()))
}

if node.TokenLiteral() == "COMPOUND_STRING" {
r := c.compileCompoundGlobal(node.Left.(ast.Nameable).IdString(), node.Right.(*ast.InfixExpression))
c.storeGlobal(node.Left.(ast.Nameable).IdString(), r)
return nil
}

r := c.compileValue(node.Right)

if _, ok := node.Right.(*ast.Instance); !ok { // If declaring a new instance don't save
switch n := node.Left.(type) {
case *ast.Identifier:
Expand Down Expand Up @@ -951,67 +962,6 @@ func (c *Compiler) compileInfixNode(node ast.Node) value.Value {
}
}

// func (c *Compiler) compileSwap(node *ast.InfixExpression) value.Value {
// n, ok := node.Left.(*ast.ParameterCall)
// pos := node.Position()
// if !ok {
// panic(fmt.Sprintf("cannot swap a non-stock or non-flow property col: %d, line: %d", pos[0], pos[1]))
// }

// rawid := n.RawId()

// s := c.specs[rawid[0]]
// spec := c.specStructs[rawid[0]]
// ty, _ := spec.GetStructType(rawid)
// if ty == "NIL" {
// panic(fmt.Sprintf("cannot send value to variable %s. Variable not defined line: %d, col: %d", strings.Join(rawid, "_"), pos[0], pos[1]))
// }

// _, err := spec.FetchVar(rawid, ty)

// if err == nil {
// r := c.compileValue(node.Right)
// pointer := s.GetSpecVarPointer(rawid)
// c.contextBlock.NewStore(r, pointer)
// return nil
// }

// var str1, str2 map[string]ast.Node
// switch ty {
// case "STOCK":
// id := n.Id()
// str1, err = spec.FetchStock(id[1])
// if err != nil {
// panic(fmt.Sprintf("cannot send value to variable %s. Variable not defined line: %d, col: %d", strings.Join(rawid, "_"), pos[0], pos[1]))
// }

// rightId := node.Right.(ast.Nameable).Id()
// str2, err = spec.FetchStock(rightId[1])

// case "FLOW":
// id := n.Id()
// str1, err = spec.FetchFlow(id[1])
// if err != nil {
// panic(fmt.Sprintf("cannot send value to variable %s. Variable not defined line: %d, col: %d", strings.Join(rawid, "_"), pos[0], pos[1]))
// }

// rightId := node.Right.(ast.Nameable).Id()
// str2, err = spec.FetchFlow(rightId[1])
// }

// if err != nil {
// panic(fmt.Sprintf("cannot send value to variable %s. Variable not defined line: %d, col: %d", strings.Join(rawid, "_"), pos[0], pos[1]))
// }

// for k := range str1 {
// from := append(rawid, k)
// to := c.compileValue(str2[k])
// pointer := s.GetSpecVarPointer(from)
// c.contextBlock.NewStore(to, pointer)
// }
// return nil
// }

func (c *Compiler) tagBuiltIns(v1 value.Value, gname string) value.Value {
// BuiltIns in a "b || b" or "b && b" construction need metadata
// so we can find parse them correctly
Expand Down Expand Up @@ -1087,6 +1037,40 @@ func (c *Compiler) compileIf(n *ast.IfExpression) {
}
}

func (c *Compiler) compileCompoundGlobal(name string, n *ast.InfixExpression) *ir.Global {
r := c.compileCompoundNode(n.Right)
l := c.compileCompoundNode(n.Left)

var ret *ir.Global
switch n.Operator {
case "&&":
v := constant.NewAnd(r, l)
ret = c.module.NewGlobalDef(name, v)
case "||":
v := constant.NewOr(r, l)
ret = c.module.NewGlobalDef(name, v)
}
return ret
}

func (c *Compiler) compileCompoundNode(n ast.Node) *ir.Global {
switch v := n.(type) {
case *ast.Identifier:
return c.specGlobals[v.IdString()]
case *ast.ParameterCall:
return c.specGlobals[v.IdString()]
case *ast.PrefixExpression:
r := c.compileCompoundNode(v.Right)
name := r.Ident()
name = fmt.Sprintf("%s_neg", util.FormatIdent(name))
return c.module.NewGlobalDef(name, constant.NewFNeg(r))
default:
r := c.compileValue(v)
name := r.Ident()
return c.module.NewGlobalDef(util.FormatIdent(name), r.(constant.Constant))
}
}

func (c *Compiler) compileConditional(n ast.Node) value.Value {
// Reformat the conditional clause to accept
// things like if a {} or if !a {} and replace them
Expand Down

0 comments on commit 86db50f

Please sign in to comment.