// SPDX-FileCopyrightText: 2024 Himbeer // // SPDX-License-Identifier: GPL-3.0-or-later package main import ( "fmt" "io" ) 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 declStmt interface { statementExpr markDecl() } type constStmt struct { name string initial exprExpr ln int } func (c *constStmt) markExpr() {} func (c *constStmt) markStmt() {} func (c *constStmt) markDecl() {} func (c *constStmt) line() int { return c.ln } type mutStmt struct { name string initial exprExpr ln int } func (m *mutStmt) markExpr() {} func (m *mutStmt) markStmt() {} func (m *mutStmt) markDecl() {} func (m *mutStmt) line() int { return m.ln } type assignmentStmt interface { statementExpr markAssign() } type assignStmt struct { name string value exprExpr ln int } func (a *assignStmt) markExpr() {} func (a *assignStmt) markStmt() {} func (a *assignStmt) markAssign() {} func (a *assignStmt) line() int { return a.ln } type addAssignStmt struct { name string value exprExpr ln int } func (a *addAssignStmt) markExpr() {} func (a *addAssignStmt) markStmt() {} func (a *addAssignStmt) markAssign() {} func (a *addAssignStmt) line() int { return a.ln } type subAssignStmt struct { name string value exprExpr ln int } func (s *subAssignStmt) markExpr() {} func (s *subAssignStmt) markStmt() {} func (s *subAssignStmt) markAssign() {} func (s *subAssignStmt) line() int { return s.ln } type mulAssignStmt struct { name string value exprExpr ln int } func (m *mulAssignStmt) markExpr() {} func (m *mulAssignStmt) markStmt() {} func (m *mulAssignStmt) markAssign() {} func (m *mulAssignStmt) line() int { return m.ln } type divAssignStmt struct { name string value exprExpr ln int } func (d *divAssignStmt) markExpr() {} func (d *divAssignStmt) markStmt() {} func (d *divAssignStmt) markAssign() {} func (d *divAssignStmt) line() int { return d.ln } type exprExpr interface { expression markExprExpr() generate(io.Writer) (string, error) } 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 } type callExpr struct { funcName string args *argument ln int } func (c *callExpr) markExpr() {} func (c *callExpr) markExprExpr() {} func (c *callExpr) markPrimaryExpr() {} func (c *callExpr) line() int { return c.ln } type argument struct { value exprExpr next *argument } type varExpr struct { name string ln int } func (v *varExpr) markExpr() {} func (v *varExpr) markExprExpr() {} func (v *varExpr) markPrimaryExpr() {} func (v *varExpr) line() int { return v.ln }