Newer
Older
use crate::lexer::ScriptTokenType;
use crate::parser::ast::*;
use crate::runtime::numbers::Number;
grammar<'a>;
pub Program: Program = {
ExpressionList => Program(<>)
};
Block: Option<ExpressionList> = {
"{" <ExpressionList?> "}" => <>,
};
ExpressionList: ExpressionList = {
<e:Expression> <b:";"?> => {
ExpressionList {
expressions: vec![e],
is_void: b.is_some(),
}
},
<e:Expression> ";" <mut ls:ExpressionList> => {
let mut new = vec![e];
new.append(&mut ls.expressions);
ExpressionList {
expressions: new,
is_void: ls.is_void,
pub Expression: Expression = {
ValueExpression => Expression::Value(<>),
VoidExpression => Expression::Void(<>),
};
VoidExpression: VoidExpression = {
AsVoid<PrintStmt> => <>,
AsVoid<ImportStmt> => <>,
AsVoid<ExportStmt> => <>,
AsValue<Literal> => <>,
AsValue<Identifier> => <>,
AsValue<IfStatement> => <>,
"(" <lhs:ValueExpression> "+" <rhs:ValueExpression> ")" => ValueExpression::Binary { lhs: Box::new(lhs), rhs: Box::new(rhs), operator: BinaryOp::Add },
"typeof" <expr:ValueExpression> => TypeofValue(Box::new(expr)).into(),
"-" <expr:ValueExpression> => ValueExpression::Unary { operand: Box::new(expr), operator: UnaryOp::Negate },
"!" <expr:ValueExpression> => ValueExpression::Unary { operand: Box::new(expr), operator: UnaryOp::Not },
"(" <expr:ValueExpression> ")" => GroupedExpression { inner: Box::new(expr) }.into(),
}
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//ValueExpression: ValueExpression = {
// #[precedence(level="100")]
// "(" <expr:ValueExpression> ")" => GroupedExpression { inner: Box::new(expr) }.into(),
// #[precedence(level="0")]
// Literal => ValueExpression::Literal(<>),
// #[precedence(level="0")]
// Identifier => <>.into(),
//
// #[precedence(level="2")]
// "typeof" <expr:ValueExpression> => TypeofValue(Box::new(expr)).into(),
// #[precedence(level="2")]
// "-" <expr:ValueExpression> => ValueExpression::Unary { operand: Box::new(expr), operator: UnaryOp::Negate },
// #[precedence(level="2")]
// "!" <expr:ValueExpression> => ValueExpression::Unary { operand: Box::new(expr), operator: UnaryOp::Not },
//
// #[precedence(level = "3")]
// IfStatement => <>.into(),
//
// #[precedence(level="4")] #[assoc(side="left")]
// <lhs:ValueExpression> "*" <rhs:ValueExpression> => {
// ValueExpression::Binary {
// lhs: Box::new(lhs),
// rhs: Box::new(rhs),
// operator: BinaryOp::Multiply,
// }
// },
// #[precedence(level="4")] #[assoc(side="left")]
// <lhs:ValueExpression> "/" <rhs:ValueExpression> => {
// ValueExpression::Binary {
// lhs: Box::new(lhs),
// rhs: Box::new(rhs),
// operator: BinaryOp::Divide,
// }
// },
// #[precedence(level="6")] #[assoc(side="left")]
// <lhs:ValueExpression> "+" <rhs:ValueExpression> => {
// ValueExpression::Binary {
// lhs: Box::new(lhs),
// rhs: Box::new(rhs),
// operator: BinaryOp::Add,
// }
// },
// #[precedence(level="6")] #[assoc(side="left")]
// <lhs:ValueExpression> "-" <rhs:ValueExpression> => {
// ValueExpression::Binary {
// lhs: Box::new(lhs),
// rhs: Box::new(rhs),
// operator: BinaryOp::Subtract,
// }
// },
//};
AsVoid<R>: VoidExpression = {
R => <>.into()
}
AsValue<R>: ValueExpression = {
R => <>.into()
}
TypeofStmt: TypeofValue = {
"typeof" <ValueExpression> => TypeofValue(Box::new(<>))
}
PrintStmt: Print = {
"print" <expr:ValueExpression> => Print { expr: Box::new(expr) },
}
ImportStmt: Import = {
"import" "{" <items:IdentifierList> "}" "from" <source:StringValue> => Import { source, items },
}
ExportStmt: Export = {
"export" "{" <items:IdentifierList> "}" => Export { items },
}
IfStatement: Conditional = {
BareIfStatement => Conditional { blocks: vec![<>], fallback: None },
<fi:BareIfStatement> "else" <bl:Block> => Conditional { blocks: vec![fi], fallback: bl },
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<fi:BareIfStatement> "else" <ls:IfStatement> => {
let mut ls = ls;
let mut new = vec![fi];
new.append(&mut ls.blocks);
Conditional {
blocks: new,
fallback: ls.fallback,
}
}
};
BareIfStatement: GuardedBlock = {
"if" <guard:ValueExpression> <bl:Block> => {
GuardedBlock {
block: bl.unwrap_or_default(),
guard: Box::new(guard),
}
}
};
ParameterList = ListOf<ValueExpression>;
IdentifierList = ListOf<IdentifierNode>;
IdentifierNode: IdentifierNode = {
IdentifierAlias => IdentifierNode::Alias(<>),
Identifier => IdentifierNode::Direct(<>),
};
IdentifierAlias: IdentifierAlias = {
<base:Identifier> "as" <alias:Identifier> => IdentifierAlias(base.0, alias.0),
};
Identifier: Identifier = {
"identifier" => Identifier(String::from(<>))
};
Literal: LiteralNode = {
"boolean" => LiteralNode::Boolean(<>),
"null" => LiteralNode::Null,
"float" => LiteralNode::Number(Number::Float(<>)),
"integer" => LiteralNode::Number(Number::Integer(<>)),
"string" => LiteralNode::String(String::from(<>)),
"owned_string" => LiteralNode::String(<>),
StringValue: String = {
"string" => String::from(<>),
"owned_string" => <>,
};
ListOf<T>: Vec<T> = {
<mut v:(<T> ",")+> <e:T?> => match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
};
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
"(" => ScriptTokenType::LeftParen,
")" => ScriptTokenType::RightParen,
"{" => ScriptTokenType::LeftBrace,
"}" => ScriptTokenType::RightBrace,
"," => ScriptTokenType::Comma,
"." => ScriptTokenType::Dot,
"-" => ScriptTokenType::Minus,
"+" => ScriptTokenType::Plus,
";" => ScriptTokenType::Semicolon,
"/" => ScriptTokenType::Slash,
"*" => ScriptTokenType::Asterisk,
"!" => ScriptTokenType::Bang,
"!=" => ScriptTokenType::BangEqual,
"=" => ScriptTokenType::Equal,
"==" => ScriptTokenType::EqualEqual,
">" => ScriptTokenType::Greater,
">=" => ScriptTokenType::GreaterEqual,
"<" => ScriptTokenType::Less,
"<=" => ScriptTokenType::LessEqual,
"||" => ScriptTokenType::DoublePipe,
"&&" => ScriptTokenType::DoubleAmpersand,
"%" => ScriptTokenType::Modulo,
"^" => ScriptTokenType::Caret,
"struct" => ScriptTokenType::Class,
"else" => ScriptTokenType::Else,
"fn" => ScriptTokenType::Function,
"for" => ScriptTokenType::For,
"if" => ScriptTokenType::If,
"null" => ScriptTokenType::Null,
"print" => ScriptTokenType::Print,
"return" => ScriptTokenType::Return,
"super" => ScriptTokenType::Super,
"this" => ScriptTokenType::This,
"let" => ScriptTokenType::Let,
"while" => ScriptTokenType::While,
"export" => ScriptTokenType::Export,
"import" => ScriptTokenType::Import,
"as" => ScriptTokenType::Alias,
"from" => ScriptTokenType::From,
"typeof" => ScriptTokenType::Typeof,
"finally" => ScriptTokenType::Finally,
"boolean" => ScriptTokenType::Boolean(<bool>),
"float" => ScriptTokenType::Float(<f64>),
"integer" => ScriptTokenType::Integer(<i64>),
"owned_string" => ScriptTokenType::OwnedString(<String>),
"string" => ScriptTokenType::String(<String>),
"identifier" => ScriptTokenType::Identifier(<String>),