[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 { struct Expression {
public: public:
/// ///
Term opBinary(string op : "+", T)(T rhs) const { Expression opBinary(string op : "+")(Term rhs) {
return Expression(terms ~ rhs); return Expression(terms ~ rhs);
} }
/// ///
Term opBinary(string op : "-", T)(T rhs) const { Expression opBinary(string op : "-")(Term rhs) {
return Expression(terms ~ rhs*(-1f)); return Expression(terms ~ rhs*(-1f));
} }
@ -23,21 +23,35 @@ struct Expression {
struct Term { struct Term {
public: public:
/// ///
alias Value = Algebraic!(float, string, FunctionCall); alias Value = Algebraic!(float, string, FunctionCall, Expression);
/// ///
Term opBinary(string op : "*", T)(T rhs) const { Term opBinary(string op : "*", T)(T rhs) {
return Term(multipled_values ~ Value(rhs), divided_values); 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 { Term opBinary(string op : "/", T)(T rhs) {
return Term(multipled_values, divided_values ~ Value(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 /// License: MIT
module sjscript.parse; module sjscript.parse;
import std.conv; import std.conv,
std.range.primitives;
import dast.parse; import dast.parse;
@ -16,24 +17,21 @@ unittest {
enum src = q"EOS enum src = q"EOS
framebuffer [0..5] { framebuffer [0..5] {
a = 0; a = 2 * distance(player_x, player_y);
b += 0; b += 0;
} }
EOS"; EOS";
try {
src. src.
Tokenize!TokenType. Tokenize!TokenType.
filter!(x => x.type != TokenType.Whitespace). filter!(x => x.type != TokenType.Whitespace).
chain([Token("", TokenType.End)]). chain([Token("", TokenType.End)]).
Parse(). Parse();
each!writeln;
} catch (ParseException!Token e) {
"%s at %s".writefln(e.msg, e.token);
}
} }
/// ///
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; 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)); ident.text, ParameterType.AddAssign, expr, CreateTokenPos(ident, semicolon));
} }
static Expression ParseExpression(@(TokenType.Number) Token) { // TODO static Expression ParseExpressionFromFirstTerm(Term term) {
return Expression(); 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 { private struct Whole {
ParametersBlock[] blocks; ParametersBlock[] blocks;
} }
private struct FunctionCallArgs {
Expression[] exprs;
}
private TokenPos CreateTokenPos(Token first, Token last) { private TokenPos CreateTokenPos(Token first, Token last) {
return TokenPos( return TokenPos(

2
thirdparty/dast vendored

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