[update] Allowed the parser to parse Expression.
This commit is contained in:
parent
398ba52c0b
commit
2858e30285
@ -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;
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -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(
|
||||
|
2
thirdparty/dast
vendored
2
thirdparty/dast
vendored
@ -1 +1 @@
|
||||
Subproject commit 0b38f7365e99e9ada6d874f1ecfc99e90e43e670
|
||||
Subproject commit 1865e404a6f318d31b3655317141d998de6654eb
|
Reference in New Issue
Block a user