diff --git a/SMILEBASIC/main.d b/SMILEBASIC/main.d index bdd72d0..d585f69 100644 --- a/SMILEBASIC/main.d +++ b/SMILEBASIC/main.d @@ -3,10 +3,8 @@ import otya.smilebasic.parser; int main(string[] argv) { writeln("Hello D-World!"); - auto parser = new Parser("1+2*(3+4)"); + auto parser = new Parser("ADD(ADD(1,2,3,4,5,6),2,3,4,5,6)"); writeln(parser.calc()); - writeln(1+2*3+4); - writeln(1+2*(3+4)); readln(); return 0; } diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index 7ff592c..bc11c26 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -1,12 +1,17 @@ module otya.smilebasic.node; import otya.smilebasic.type; import otya.smilebasic.token; +import std.container; + enum NodeType { Node, Expression, Constant, BinaryOperator, + Variable, + CallFunction, + VoidExpression, } abstract class Node { @@ -49,3 +54,34 @@ class BinaryOperator : Expression this.item2 = i2; } } +class Variable : Expression +{ + wstring name; + this(wstring n) + { + this.type = NodeType.Variable; + this.name = n; + } +} +class CallFunction : Expression +{ + wstring name; + Expression[] args; + this(wstring n) + { + this.type = NodeType.CallFunction; + this.name = n; + args = new Expression[0]; + } + void addArg(Expression arg) + { + args ~= arg; + } +} +class VoidExpression : Expression +{ + this() + { + this.type = NodeType.VoidExpression; + } +} diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 11b2be3..d499a7d 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -23,6 +23,7 @@ class Lexical table['/'] = TokenType.Div; table['('] = TokenType.LParen; table[')'] = TokenType.RParen; + table[','] = TokenType.Comma; } bool empty() { @@ -56,6 +57,21 @@ class Lexical token = Token(TokenType.Integer, Value(num)); break; } + if(c.isAlpha()) + { + wstring iden; + for(;i < code.length;i++) + { + c = code[i]; + if(!c.isAlpha()) + { + break; + } + iden ~= c; + } + token = Token(TokenType.Iden, Value(iden)); + break; + } if(table[cast(char)c] == TokenType.Unknown) { //error @@ -173,6 +189,22 @@ class Parser } } break; + case NodeType.Variable: + return 100; + case NodeType.CallFunction: + { + auto func = cast(CallFunction)exp; + int result = 100; + if(func.name == "ADD") + { + result = 0; + foreach(Expression i ; func.args) + { + result += calc(i); + } + } + return result; + } default: return - - -1; } @@ -224,6 +256,35 @@ class Parser version(none)stdout.flush(); node = new Constant(Value(token.value.integerValue)); break; + case TokenType.Iden: + if(!lex.empty()) + lex.popFront(); + if(lex.front().type == TokenType.LParen) + { + auto func = new CallFunction(token.value.stringValue); + node = func; + //関数呼び出しだった + while(true) + { + lex.popFront(); + token = lex.front(); + + if(token.type == TokenType.Comma) + { + func.addArg(new VoidExpression()); + lex.popFront(); + token = lex.front(); + } + else + func.addArg(expression()); + if(lex.front().type == TokenType.RParen) break; + } + } + else + { + return new Variable(token.value.stringValue); + } + break; case TokenType.LParen: lex.popFront(); node = expression(); diff --git a/SMILEBASIC/token.d b/SMILEBASIC/token.d index f7252e8..2efc607 100644 --- a/SMILEBASIC/token.d +++ b/SMILEBASIC/token.d @@ -18,6 +18,8 @@ enum TokenType If, LParen, RParen, + Iden, + Comma, } struct Token