Skip to content
Snippets Groups Projects
Verified Commit 97edbf3f authored by Louis's avatar Louis :fire:
Browse files

Add import/export/while to grammar

parent ab558877
No related branches found
No related tags found
No related merge requests found
......@@ -6,46 +6,19 @@ grammar<'a>;
pub Program: Program = {
<ExpressionList> => Program(<>),
}
ExpressionBlock: ExpressionList = {
"{" "}" => ExpressionList::empty(),
"{" <ExpressionList> "}" => <>,
}
ExpressionList: ExpressionList = {
<Expression> => ExpressionList::production(vec![<>]),
<mut list:ExpressionList> ";" <expr:Expression> => {
list.expressions.push(expr);
list
},
<mut opt:ExpressionList> ";" => {
opt.is_void = true;
opt
},
}
FunctionDeclParamList = CommaSeperatedList<FunctionDeclParam>;
FunctionDeclParam: DeclareIdent = {
Identifier => DeclareIdent::WithoutValue(<>),
<id:Identifier> "=" <def:ValueExpression> => DeclareIdent::WithValue(Assignment {
ident: id,
value: Box::new(def),
}),
}
};
ParameterList: Vec<ValueExpression> = {
"(" <CommaSeperatedValueExpressionList> ")" => <>,
"(" ")" => Vec::new(),
}
};
CommaSeperatedValueExpressionList = CommaSeperatedList<ValueExpression>;
pub Expression: Expression = {
ValueExpression => Expression::Value(<>),
VoidExpression => Expression::Void(<>),
}
};
ValueExpression: ValueExpression = {
FirstClassDeclareExpression => <>,
......@@ -53,32 +26,34 @@ ValueExpression: ValueExpression = {
"let" <id:Identifier> "=" <expr:FirstClassDeclareExpression> => DeclareIdent::WithValue(
Assignment { ident: id, value :Box::new(expr) }
).into(),
}
};
VoidExpression: VoidExpression = {
UnaryStatement => <>
}
UnaryStatement => <>,
IOStatement => <>,
ConditionalLoop => <>.into(),
};
FirstClassDeclareExpression: ValueExpression = {
BoolOrExpression => <>,
DeclareFunction => <>.into(),
}
};
BoolOrExpression: ValueExpression = {
BoolAndExpression => <>,
<lhs:BoolOrExpression> "||" <rhs:BoolAndExpression> => ValueExpression::bool_or(lhs, rhs),
}
};
BoolAndExpression: ValueExpression = {
EqualityExpression => <>,
<lhs:BoolAndExpression> "&&" <rhs:EqualityExpression> => ValueExpression::bool_and(lhs, rhs),
}
};
EqualityExpression: ValueExpression = {
ComparisonExpression => <>,
<lhs:EqualityExpression> "==" <rhs:ComparisonExpression> => ValueExpression::equals(lhs, rhs),
<lhs:EqualityExpression> "!=" <rhs:ComparisonExpression> => ValueExpression::not_equals(lhs, rhs),
}
};
ComparisonExpression: ValueExpression = {
AdditiveExpression => <>,
......@@ -86,32 +61,37 @@ ComparisonExpression: ValueExpression = {
<lhs:ComparisonExpression> ">" <rhs:AdditiveExpression> => ValueExpression::greater_than(lhs, rhs),
<lhs:ComparisonExpression> "<=" <rhs:AdditiveExpression> => ValueExpression::greater_than_equal(lhs, rhs),
<lhs:ComparisonExpression> ">=" <rhs:AdditiveExpression> => ValueExpression::greater_than_equal(lhs, rhs),
}
};
AdditiveExpression: ValueExpression = {
MultiplicativeExpression => <>,
<lhs:AdditiveExpression> "+" <rhs:MultiplicativeExpression> => ValueExpression::add(lhs, rhs),
<lhs:AdditiveExpression> "-" <rhs:MultiplicativeExpression> => ValueExpression::sub(lhs, rhs),
}
};
MultiplicativeExpression: ValueExpression = {
UnaryExpression => <>,
<lhs:MultiplicativeExpression> "*" <rhs:UnaryExpression> => ValueExpression::mul(lhs, rhs),
<lhs:MultiplicativeExpression> "/" <rhs:UnaryExpression> => ValueExpression::div(lhs, rhs),
<lhs:MultiplicativeExpression> "%" <rhs:UnaryExpression> => ValueExpression::modulo(lhs, rhs),
}
};
IOStatement: VoidExpression = {
"import" "{" <items:CommaSeperatedList<IdentifierNode>> "}" "from" <source:StringValue> => Import { items, source }.into(),
"export" "{" <items:CommaSeperatedList<IdentifierNode>> "}" => Export { items }.into(),
};
UnaryStatement: VoidExpression = {
"print" <FirstClassDeclareExpression> => Print { expr: Box::new(<>) }.into(),
"return" <FirstClassDeclareExpression> => Return { expr: Box::new(<>) }.into(),
}
};
UnaryExpression: ValueExpression = {
IndexedExpression => <>,
"typeof" <UnaryExpression> => TypeofValue(Box::new(<>)).into(),
"!" <UnaryExpression> => ValueExpression::Unary { operand: Box::new(<>), operator: UnaryOp::Not },
"-" <UnaryExpression> => ValueExpression::Unary { operand: Box::new(<>), operator: UnaryOp::Negate },
}
};
IndexedExpression: ValueExpression = {
CallExpression => <>,
......@@ -119,19 +99,36 @@ IndexedExpression: ValueExpression = {
initialiser: Box::new(init),
path: acc,
}.into(),
}
};
CallExpression: ValueExpression = {
BaseExpression => <>,
FunctionCall => <>.into(),
}
};
BaseExpression: ValueExpression = {
Literal => <>.into(),
Identifier => <>.into(),
Conditional => <>,
"(" <ValueExpression> ")" => GroupedExpression { inner: Box::new(<>) }.into(),
}
};
ExpressionBlock: ExpressionList = {
"{" <ExpressionList> "}" => <>,
"{" "}" => ExpressionList::empty(),
};
ExpressionList: ExpressionList = {
<Expression> => ExpressionList::production(vec![<>]),
<mut list:ExpressionList> ";" <expr:Expression> => {
list.expressions.push(expr);
list
},
<mut opt:ExpressionList> ";" => {
opt.is_void = true;
opt
},
};
DeclareFunction: DeclareFunction = {
"fn" <ident:Identifier> "(" <params:FunctionDeclParamList?> ")" <body:ExpressionBlock> => DeclareFunction {
......@@ -139,7 +136,17 @@ DeclareFunction: DeclareFunction = {
params: params.unwrap_or_default(),
body,
}
}
};
FunctionDeclParamList = CommaSeperatedList<FunctionDeclParam>;
FunctionDeclParam: DeclareIdent = {
Identifier => DeclareIdent::WithoutValue(<>),
<id:Identifier> "=" <def:ValueExpression> => DeclareIdent::WithValue(Assignment {
ident: id,
value: Box::new(def),
}),
};
AccessorChainAnyEnding: Vec<AccessorType> = {
AccessorChainEndingWithProperty => <>,
......@@ -148,7 +155,7 @@ AccessorChainAnyEnding: Vec<AccessorType> = {
ls.push(AccessorType::FunctionCall(func));
ls
},
}
};
AccessorChainEndingWithProperty: Vec<AccessorType> = {
Identifier => vec![AccessorType::Identifier(<>)],
......@@ -165,12 +172,12 @@ AccessorChainEndingWithProperty: Vec<AccessorType> = {
first.push(AccessorType::Identifier(id));
first
},
}
};
Conditional: ValueExpression = {
GuardedBlockList => Conditional { blocks: <>, fallback: None }.into(),
<ls:GuardedBlockList> "else" <fb:ExpressionBlock> => Conditional { blocks: ls, fallback: Some(fb) }.into(),
}
};
GuardedBlockList: Vec<GuardedBlock> = {
GuardedBlock => vec![<>],
......@@ -178,24 +185,46 @@ GuardedBlockList: Vec<GuardedBlock> = {
ls.push(gb);
ls
},
}
};
GuardedBlock: GuardedBlock = {
"if" <guard:ValueExpression> <block:ExpressionBlock> => GuardedBlock {
guard: Box::new(guard),
block,
},
}
};
ConditionalLoop: ConditionalLoop = {
"while" <guard: ValueExpression> <block:ExpressionBlock> => ConditionalLoop {
block: GuardedBlock {
guard: Box::new(guard),
block,
},
fallback: None,
},
"while" <guard: ValueExpression> <block:ExpressionBlock> "finally" <fallback:ExpressionBlock> => ConditionalLoop {
block: GuardedBlock {
guard: Box::new(guard),
block,
},
fallback: Some(fallback),
},
};
FunctionCall: FunctionCall = {
<id:Identifier> <params:ParameterList> => FunctionCall {
name: id,
params,
}
}
};
IdentifierNode: IdentifierNode = {
Identifier => IdentifierNode::Direct(<>),
IdentifierAsAlias => IdentifierNode::Alias(<>),
};
IdentifierAsAlias: IdentifierAlias = {
<base:Identifier> "as" <alias:Identifier> => IdentifierAlias(base.0, alias.0),
<base:"identifier"> "as" <alias:"identifier"> => IdentifierAlias(base, alias),
};
Identifier: Identifier = {
......@@ -222,7 +251,7 @@ CommaSeperatedList<Type>: Vec<Type> = {
ls.push(ty);
ls
}
}
};
extern {
type Location = usize;
......
import { random_float, random_int, random_bool } from "@runtime:random"
import { truncate } from "@runtime:maths"
import { random_float, random_int, random_bool } from "@runtime:random";
import { truncate } from "@runtime:maths";
let var_a = random_int(0, 10) >= 5;
let var_b = random_bool();
......@@ -7,4 +7,12 @@ let my_var = if if 1 + 2 > 4 { var_a } else { var_b } {
truncate(random_float() * 10)
} else {
random_int(100, 200)
};
export { my_var };
while some_expression {
print "foo";
} finally {
print "bar";
};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment