diff --git a/sjscript/src/sjscript/Expression.d b/sjscript/src/sjscript/Expression.d index 895a523..6f94c50 100644 --- a/sjscript/src/sjscript/Expression.d +++ b/sjscript/src/sjscript/Expression.d @@ -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; } /// diff --git a/sjscript/src/sjscript/parse.d b/sjscript/src/sjscript/parse.d index 85b23af..c43fb93 100644 --- a/sjscript/src/sjscript/parse.d +++ b/sjscript/src/sjscript/parse.d @@ -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); - } + + src. + Tokenize!TokenType. + filter!(x => x.type != TokenType.Whitespace). + chain([Token("", TokenType.End)]). + 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( diff --git a/thirdparty/dast b/thirdparty/dast index 0b38f73..1865e40 160000 --- a/thirdparty/dast +++ b/thirdparty/dast @@ -1 +1 @@ -Subproject commit 0b38f7365e99e9ada6d874f1ecfc99e90e43e670 +Subproject commit 1865e404a6f318d31b3655317141d998de6654eb