1 module zua.parser.ast; 2 import zua.parser.lexer; 3 import zua.compiler.ir : BinaryOperation, UnaryOperation; 4 import std.typecons; 5 import std.variant; 6 7 /** Represents a single AST node */ 8 abstract class AstNode { 9 /** The range of tokens that represent this AST node */ 10 Token start; 11 Token end; /// ditto 12 } 13 14 /** A statement */ 15 abstract class Stat : AstNode {} 16 17 /** An erroneous statement */ 18 final class ErrorStat : Stat {} 19 20 /** An assignment statement */ 21 final class AssignStat : Stat { 22 /** A list of lvalues to modify */ 23 LvalueExpr[] keys; 24 25 /** The values to set each variable to */ 26 Expr[] values; 27 } 28 29 /** An expression statement */ 30 final class ExprStat : Stat { 31 /** The expression to evaluate in this statement */ 32 Expr expr; 33 } 34 35 /** A block statement */ 36 final class Block : Stat { 37 /** A list of statements to be executed by this block */ 38 Stat[] body; 39 } 40 41 /** A local variable declaration statement */ 42 final class DeclarationStat : Stat { 43 /** A list of variables to declare */ 44 string[] keys; 45 46 /** The values to set each variable to */ 47 Expr[] values; 48 } 49 50 /** A local function declaration statement */ 51 final class FunctionDeclarationStat : Stat { 52 /** The variable to declare */ 53 string key; 54 55 /** The value to assign it */ 56 FunctionExpr value; 57 } 58 59 /** A while statement */ 60 final class WhileStat : Stat { 61 /** The condition for this while statement */ 62 Expr cond; 63 64 /** The body of this while statement */ 65 Block body; 66 } 67 68 /** A repeat statement */ 69 final class RepeatStat : Stat { 70 /** The end condition for this repeat statement */ 71 Expr endCond; 72 73 /** The body of this repeat statement */ 74 Block body; 75 } 76 77 alias IfEntry = Tuple!(Expr, "cond", Block, "body"); 78 79 /** An if statement */ 80 final class IfStat : Stat { 81 /** The various condition-code pairs in this if statement */ 82 IfEntry[] entries; 83 84 /** The 'else' body of this if statement */ 85 Nullable!Block elseBody; 86 } 87 88 /** A numeric for loop */ 89 final class NumericForStat : Stat { 90 /** The variable to use in this for loop */ 91 string var; 92 93 /** Defines the range to loop over */ 94 Expr low; 95 Expr high; /// ditto 96 Nullable!Expr step; /// ditto 97 98 /** The body of the for loop */ 99 Block body; 100 } 101 102 /** A foreach loop */ 103 final class ForeachStat : Stat { 104 /** The variables to use in this for loop */ 105 string[] vars; 106 107 /** Defines the iterator to loop over */ 108 Expr[] iter; 109 110 /** The body of the for loop */ 111 Block body; 112 } 113 114 /** A return statement */ 115 final class ReturnStat : Stat { 116 /** The values to return */ 117 Expr[] values; 118 } 119 120 /** A type of atomic statement */ 121 enum AtomicStatType { 122 Break 123 } 124 125 /** An atomic statement */ 126 final class AtomicStat : Stat { 127 /** The type of atomic statement this represents */ 128 AtomicStatType type; 129 } 130 131 /** An expression */ 132 abstract class Expr : AstNode {} 133 134 /** An erroneous expression */ 135 final class ErrorExpr : LvalueExpr {} 136 137 /** A prefix expression */ 138 abstract class PrefixExpr : Expr {} 139 140 /** An expression whose value can be set */ 141 abstract class LvalueExpr : PrefixExpr {} 142 143 /** A variable expression */ 144 final class VariableExpr : LvalueExpr { 145 /** The name of this variable */ 146 string name; 147 } 148 149 /** An index expression */ 150 final class IndexExpr : LvalueExpr { 151 /** The object to index */ 152 Expr base; 153 154 /** The key to use in indexing the given object */ 155 Expr key; 156 } 157 158 /** A bracket expression */ 159 final class BracketExpr : PrefixExpr { 160 /** The expression in the bracket expression */ 161 Expr expr; 162 } 163 164 /** A function call expression */ 165 final class CallExpr : PrefixExpr { 166 Expr base; /** The base of the call expression */ 167 Expr[] args; /** The arguments to use in the call */ 168 169 /** 170 * The method name to use in the call. 171 * If supplied, the call is a selfcall, i.e. 'base:method(args)' is called. 172 * Otherwise, 'base' is treated as a function, i.e. 'base(args)' is called. 173 */ 174 Nullable!string method; 175 } 176 177 /** A type of atomic expression */ 178 enum AtomicExprType { 179 Nil, 180 False, 181 True, 182 VariadicTuple 183 } 184 185 /** An atomic expression */ 186 final class AtomicExpr : Expr { 187 /** The type of atomic expression this represents */ 188 AtomicExprType type; 189 } 190 191 /** A number expression */ 192 final class NumberExpr : Expr { 193 /** The value of this expression */ 194 double value; 195 } 196 197 /** A string expression */ 198 final class StringExpr : Expr { 199 /** The value of this expression */ 200 string value; 201 } 202 203 /** A function expression */ 204 final class FunctionExpr : Expr { 205 /** A list of argument names */ 206 string[] args; 207 208 /** Determines if the function is variadic */ 209 bool variadic; 210 211 /** The body of the function */ 212 Block body; 213 } 214 215 /** A binary operation expression */ 216 final class BinaryExpr : Expr { 217 /** The token representing this operation */ 218 Token opToken; 219 220 /** The operation performed on the two sides */ 221 BinaryOperation op; 222 223 Expr lhs; /** The left-hand side of the expression */ 224 Expr rhs; /** The right-hand side of the expression */ 225 } 226 227 /** A unary operation expression */ 228 final class UnaryExpr : Expr { 229 /** The operation performed on the given expression */ 230 UnaryOperation op; 231 232 /** The expression to manipulate using the given unary operation */ 233 Expr expr; 234 } 235 236 /** A single field in a table */ 237 struct TableField { 238 /** The key component of this field */ 239 Expr key; 240 241 /** The value component of this field */ 242 Expr value; 243 } 244 245 alias FieldEntry = Algebraic!(TableField, Expr); 246 247 /** A table constructor expression */ 248 final class TableExpr : Expr { 249 /** A list of fields in the table */ 250 FieldEntry[] fields; 251 }