public FuncInvoke(Token token, List<Ast> args) : base(token) { FunctionName = new Expr(token); Arguments = args; }
public VarDeclrAst(Token declType, Token name) : base(name) { DeclarationType = new Expr(declType); VariableName = new Expr(name); }
public MethodDeclr(Token returnType, Token funcName, List<Ast> arguments, ScopeDeclr body, bool isAnon = false) : base(funcName) { MethodReturnType = new Expr(returnType); MethodName = new Expr(funcName); Arguments = arguments; Body = body; IsAnonymous = isAnon; }
public void Visit(Expr ast) { if (ast.Left != null) { ast.Left.Visit(this); } Console.Write(" " + ast.Token); if (ast.Right != null) { Console.Write(" "); ast.Right.Visit(this); Console.WriteLine(); } }
private Ast SingleToken() { if (IsValidOperand()) { var token = new Expr(TokenStream.Take(TokenStream.Current.TokenType)); return token; } return null; }
private Ast New() { Func<Ast> op = () => { if (TokenStream.Current.TokenType == TokenType.New) { TokenStream.Take(TokenType.New); if (ValidNewable()) { var name = new Expr(TokenStream.Take(TokenStream.Current.TokenType)); if (TokenStream.Current.TokenType == TokenType.LSquareBracket) { TokenStream.Take(TokenType.LSquareBracket); var size = Expression(); TokenStream.Take(TokenType.RSquareBracket); return new NewArrayAst(name, size); } var args = GetArgumentList(); return new NewAst(name, args); } } if (TokenStream.Current.TokenType == TokenType.OpenParenth && TokenStream.Peek(1).TokenType == TokenType.New) { TokenStream.Take(TokenType.OpenParenth); var item = New(); TokenStream.Take(TokenType.CloseParenth); return item; } return null; }; return TokenStream.Capture(op); }
public void Visit(Expr ast) { Exec(ast); }
private dynamic Expression(Expr ast) { var lhs = ast.Left; var rhs = ast.Right; switch (ast.Token.TokenType) { case TokenType.Equals: if (lhs.AstType == AstTypes.ClassRef) { // a litle trickery here. create a copy of the class reference // with everytihng up to the second to last item. this gives you // the workign memory space that the very last item should sit in // then lets execute this as if we are asking for the memory space // and finally assign the very last symbol to the calculated memory // space we got var classRef = (lhs as ClassReference); var lastItem = classRef.Deferences.Last(); var fakeRef = new ClassReference(classRef.ClassInstance, classRef.Deferences.Take(classRef.Deferences.Count - 1) .ToList()); var space = GetValue(Exec(fakeRef)); Assign(lastItem, Exec(rhs), space); } else { ValueMemory itemSpace = Get(lhs); Assign(lhs, Exec(rhs), itemSpace != null ? itemSpace.Memory : null); } return null; case TokenType.Word: return Get(ast); case TokenType.Int: return Convert.ToInt32(ast.Token.TokenValue); case TokenType.Float: return Convert.ToDouble(ast.Token.TokenValue); case TokenType.QuotedString: return ast.Token.TokenValue; case TokenType.Nil: return TokenType.Nil; case TokenType.True: return true; case TokenType.False: return false; } if (TokenUtil.IsOperator(ast.Token)) { return ApplyOperation(ast); } return null; }
private object ApplyOperation(Expr ast) { dynamic leftExec = Exec(ast.Left); var left = leftExec is ValueMemory ? (leftExec as ValueMemory).Value : leftExec; // short circuit if (ast.Token.TokenType == TokenType.Or) { if (left is bool && left == true) { return true; } } if (ast.Token.TokenType == TokenType.Compare) { if (left is bool && left == false) { return false; } } dynamic rightExec = Exec(ast.Right); var right = rightExec is ValueMemory ? (rightExec as ValueMemory).Value : rightExec; switch (ast.Token.TokenType) { case TokenType.Compare: if (left is TokenType || right is TokenType) { return NullTester.NullEqual(left, right); } return left == right; case TokenType.NotCompare: if (left is TokenType || right is TokenType) { return !NullTester.NullEqual(left, right); } return left != right; case TokenType.GreaterThan: return left > right; case TokenType.LessThan: return left < right; case TokenType.Plus: return left + right; case TokenType.Minus: return left - right; case TokenType.Slash: return left/right; case TokenType.Carat: return left ^ right; case TokenType.Ampersand: return left && right; case TokenType.Or: return left || right; } return null; }
public void Visit(Expr ast) { if (ast.Left != null) { ast.Left.Visit(this); } if (ast.Right != null) { ast.Right.Visit(this); } SetScope(ast); if (ast.Left == null && ast.Right == null) { ast.AstSymbolType = ResolveOrDefine(ast); } else { if (ResolvingTypes) { ast.AstSymbolType = GetExpressionType(ast.Left, ast.Right, ast.Token); } } }
/// <summary> /// Creates a type for built in types or resolves user defined types /// </summary> /// <param name="ast"></param> /// <returns></returns> private IType ResolveOrDefine(Expr ast) { if (ast == null) { return null; } switch (ast.Token.TokenType) { case TokenType.Word: return ResolveType(ast); } return ScopeUtil.CreateSymbolType(ast); }