diff options
Diffstat (limited to 'expression.go')
-rw-r--r-- | expression.go | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/expression.go b/expression.go new file mode 100644 index 0000000..0498d35 --- /dev/null +++ b/expression.go @@ -0,0 +1,251 @@ +package main + +import "fmt" + +type expression interface { + markExpr() + line() int +} + +type rootExpr struct { + toplevels []expression + ln int +} + +func (r *rootExpr) markExpr() {} + +func (r *rootExpr) line() int { return r.ln } + +type linkage int + +const ( + defaultLinkage linkage = iota + exportLinkage +) + +func (l linkage) String() string { + switch l { + case exportLinkage: + return "export" + } + + return "" +} + +type functionExpr struct { + link linkage + name string + params *paramExpr + returnType string + blk *blockExpr + ln int +} + +func (f *functionExpr) markExpr() {} + +func (f *functionExpr) line() int { return f.ln } + +type paramExpr struct { + name string + typ string + next *paramExpr + ln int +} + +func (p *paramExpr) markExpr() {} + +func (p *paramExpr) line() int { return p.ln } + +func (p *paramExpr) String() string { + if p == nil { + return "" + } + + s := fmt.Sprintf("%s %%%s", p.typ, p.name) + if p.next != nil { + s += p.next.String() + } + + return s +} + +type blockExpr struct { + stmts []statementExpr + ln int +} + +func (b *blockExpr) markExpr() {} + +func (b *blockExpr) line() int { return b.ln } + +type statementExpr interface { + expression + markStmt() +} + +type returnStmt struct { + value exprExpr + ln int +} + +func (r *returnStmt) markExpr() {} + +func (r *returnStmt) markStmt() {} + +func (r *returnStmt) line() int { return r.ln } + +type exprExpr interface { + expression + markExprExpr() +} + +type equalityExpr struct { + lhs *comparisonExpr + rhs []*equalityRhs + ln int +} + +func (e *equalityExpr) markExpr() {} + +func (e *equalityExpr) markExprExpr() {} + +func (e *equalityExpr) line() int { return e.ln } + +type equalityRhs struct { + op equalityOp + value *comparisonExpr +} + +type comparisonExpr struct { + lhs *termExpr + rhs *comparisonRhs + ln int +} + +func (c *comparisonExpr) markExpr() {} + +func (c *comparisonExpr) markExprExpr() {} + +func (c *comparisonExpr) line() int { return c.ln } + +type comparisonRhs struct { + op comparisonOp + value *termExpr +} + +type termExpr struct { + lhs *numeralExpr + rhs []*termRhs + ln int +} + +func (t *termExpr) markExpr() {} + +func (t *termExpr) markExprExpr() {} + +func (t *termExpr) line() int { return t.ln } + +type termRhs struct { + op shiftOp + value *numeralExpr +} + +type numeralExpr struct { + lhs *factorExpr + rhs []*numeralRhs + ln int +} + +func (n *numeralExpr) markExpr() {} + +func (n *numeralExpr) markExprExpr() {} + +func (n *numeralExpr) line() int { return n.ln } + +type numeralRhs struct { + op addSubOp + value *factorExpr +} + +type factorExpr struct { + lhs *unaryExpr + rhs []*factorRhs + ln int +} + +func (f *factorExpr) markExpr() {} + +func (f *factorExpr) markExprExpr() {} + +func (f *factorExpr) line() int { return f.ln } + +type factorRhs struct { + op mulDivOp + value *unaryExpr +} + +type unaryExpr struct { + op unaryOp + value primaryExpr + ln int +} + +func (u *unaryExpr) markExpr() {} + +func (u *unaryExpr) markExprExpr() {} + +func (u *unaryExpr) line() int { return u.ln } + +type primaryExpr interface { + exprExpr + markPrimaryExpr() +} + +type literalExpr interface { + primaryExpr + markLiteralExpr() +} + +type stringExpr struct { + segments []string + ln int +} + +func (s *stringExpr) markExpr() {} + +func (s *stringExpr) markExprExpr() {} + +func (s *stringExpr) markPrimaryExpr() {} + +func (s *stringExpr) markLiteralExpr() {} + +func (s *stringExpr) line() int { return s.ln } + +type numberExpr struct { + typ string + s string + ln int +} + +func (n *numberExpr) markExpr() {} + +func (n *numberExpr) markExprExpr() {} + +func (n *numberExpr) markPrimaryExpr() {} + +func (n *numberExpr) markLiteralExpr() {} + +func (n *numberExpr) line() int { return n.ln } + +type groupingExpr struct { + inner exprExpr + ln int +} + +func (g *groupingExpr) markExpr() {} + +func (g *groupingExpr) markExprExpr() {} + +func (g *groupingExpr) markPrimaryExpr() {} + +func (g *groupingExpr) line() int { return g.ln } |