[update] Allowed the parser to parse Expression.

This commit is contained in:
falsycat 2019-10-04 00:00:00 +00:00
parent 398ba52c0b
commit 2858e30285
3 changed files with 88 additions and 25 deletions

View File

@ -7,11 +7,11 @@ import std.variant;
struct Expression {
public:
///
Term opBinary(string op : "+", T)(T rhs) const {
Expression opBinary(string op : "+")(Term rhs) {
return Expression(terms ~ rhs);
}
///
Term opBinary(string op : "-", T)(T rhs) const {
Expression opBinary(string op : "-")(Term rhs) {
return Expression(terms ~ rhs*(-1f));
}
@ -23,21 +23,35 @@ struct Expression {
struct Term {
public:
///
alias Value = Algebraic!(float, string, FunctionCall);
alias Value = Algebraic!(float, string, FunctionCall, Expression);
///
Term opBinary(string op : "*", T)(T rhs) const {
return Term(multipled_values ~ Value(rhs), divided_values);
Term opBinary(string op : "*", T)(T rhs) {
static if (is(T == Term)) {
return Term(
numerator ~ rhs.numerator,
denominator ~ rhs.denominator);
} else {
return Term(
numerator ~ Value(rhs), denominator);
}
}
///
Term opBinary(string op : "/", T)(T rhs) const {
return Term(multipled_values, divided_values ~ Value(rhs));
Term opBinary(string op : "/", T)(T rhs) {
static if (is(T == Term)) {
return Term(
numerator ~ rhs.denominator,
denominator ~ rhs.numerator);
} else {
return Term(
numerator, denominator ~ Value(rhs));
}
}
///
Value[] multipled_values;
Value[] numerator;
///
Value[] divided_values;
Value[] denominator;
}
///

View File

@ -1,7 +1,8 @@
/// License: MIT
module sjscript.parse;
import std.conv;
import std.conv,
std.range.primitives;
import dast.parse;
@ -16,24 +17,21 @@ unittest {
enum src = q"EOS
framebuffer [0..5] {
a = 0;
a = 2 * distance(player_x, player_y);
b += 0;
}
EOS";
try {
src.
Tokenize!TokenType.
filter!(x => x.type != TokenType.Whitespace).
chain([Token("", TokenType.End)]).
Parse().
each!writeln;
} catch (ParseException!Token e) {
"%s at %s".writefln(e.msg, e.token);
}
Parse();
}
///
ParametersBlock[] Parse(R)(R tokens) {
ParametersBlock[] Parse(R)(R tokens)
if (isInputRange!R && is(ElementType!R == Token)) {
return dast.parse.Parse!Whole(tokens, cast(RuleSet) null).blocks;
}
@ -97,14 +95,65 @@ private class RuleSet {
ident.text, ParameterType.AddAssign, expr, CreateTokenPos(ident, semicolon));
}
static Expression ParseExpression(@(TokenType.Number) Token) { // TODO
return Expression();
static Expression ParseExpressionFromFirstTerm(Term term) {
return Expression([term]);
}
static Expression ParseExpressionFromFollowingAddedTerm(
Expression expr, @(TokenType.Add) Token, Term term) {
return expr + term;
}
static Expression ParseExpressionFromFollowingSubtractedTerm(
Expression expr, @(TokenType.Sub) Token, Term term) {
return expr - term;
}
static Term ParseNumberTerm(@(TokenType.Number) Token number) {
return Term([Term.Value(number.text.to!float)], []);
}
static Term ParseVariableTerm(@(TokenType.Ident) Token var) {
return Term([Term.Value(var.text)], []);
}
static Term ParseFunctionCallTerm(FunctionCall fcall) {
return Term([Term.Value(fcall)], []);
}
static Term ParseExpressionTerm(
@(TokenType.OpenParen) Token,
Expression expr,
@(TokenType.CloseParen) Token) {
return Term([Term.Value(expr)], []);
}
static Term ParseTermFromMultipledTerm(
Term lterm, @(TokenType.Mul) Token, Term rterm) {
return lterm * rterm;
}
static Term ParseTermFromDividedTerm(
Term lterm, @(TokenType.Div) Token, Term rterm) {
return lterm / rterm;
}
static FunctionCall ParseFunctionCall(
@(TokenType.Ident) Token name,
@(TokenType.OpenParen) Token,
FunctionCallArgs args,
@(TokenType.CloseParen) Token) {
return FunctionCall(name.text, args.exprs);
}
static FunctionCallArgs ParseFunctionCallArgsFirstItem(Expression expr) {
return FunctionCallArgs([expr]);
}
static FunctionCallArgs ParseFunctionCallArgsFollowingItem(
FunctionCallArgs args, @(TokenType.Comma) Token, Expression expr) {
return FunctionCallArgs(args.exprs ~ expr);
}
}
private struct Whole {
ParametersBlock[] blocks;
}
private struct FunctionCallArgs {
Expression[] exprs;
}
private TokenPos CreateTokenPos(Token first, Token last) {
return TokenPos(

2
thirdparty/dast vendored

@ -1 +1 @@
Subproject commit 0b38f7365e99e9ada6d874f1ecfc99e90e43e670
Subproject commit 1865e404a6f318d31b3655317141d998de6654eb