public Conditional(Token conditionalType, Ast predicate, ScopeDeclr body, Conditional alternate = null) : this(conditionalType) { Predicate = predicate; Body = body; Alternate = alternate; }
public BuiltInType(ExpressionTypes type, Ast src = null) : base(type.ToString()) { ExpressionType = type; Src = src; }
public VarDeclrAst(Token declType, Token name, Ast value) : base(name) { DeclarationType = new Expr(declType); VariableValue = value; VariableName = new Expr(name); }
public void Start(Ast ast) { LambdaDeclr.LambdaCount = 0; if (ast.Global != null) { Global = ast.Global; } ast.Visit(this); }
public ForLoop(Ast init, Ast stop, Ast modify, ScopeDeclr body) : base(new Token(TokenType.For)) { Setup = init; Predicate = stop; Update = modify; Body = body; }
public void Start(Ast ast) { var scopeBuilder = new ScopeBuilderVisitor(); var resolver = new ScopeBuilderVisitor(true); scopeBuilder.Start(ast); resolver.Start(ast); Global = MemorySpaces.Current; ast.Visit(this); }
public static IType CreateSymbolType(Ast astType) { if (astType == null) { return null; } Func<IType> op = () => { switch (astType.Token.TokenType) { case TokenType.Int: return new BuiltInType(ExpressionTypes.Int); case TokenType.Float: return new BuiltInType(ExpressionTypes.Float); case TokenType.Void: return new BuiltInType(ExpressionTypes.Void); case TokenType.Infer: return new BuiltInType(ExpressionTypes.Inferred); case TokenType.QuotedString: case TokenType.String: return new BuiltInType(ExpressionTypes.String); case TokenType.Word: return new UserDefinedType(astType.Token.TokenValue); case TokenType.True: case TokenType.False: return new BuiltInType(ExpressionTypes.Boolean); case TokenType.Method: return new BuiltInType(ExpressionTypes.Method); } return null; }; var type = op(); if (type != null) { type.Src = astType; } return type; }
private bool StatementExpectsSemiColon(Ast statement) { return !(statement is MethodDeclr || statement is Conditional || statement is WhileLoop || statement is TryCatchAst || statement is ForLoop); }
public void AddChild(Ast child) { if (child != null) { Children.Add(child); } }
public WhileLoop(Ast predicate, ScopeDeclr body) : this(new Token(TokenType.While)) { Predicate = predicate; Body = body; }
public ArrayDeclrAst(Token declType, Token name, Ast value) : base(declType, name, value) { IsArray = true; }
/// <summary> /// Determines user type /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="token"></param> /// <returns></returns> public static IType GetExpressionType(Ast left, Ast right, Token token) { switch (token.TokenType) { case TokenType.Ampersand: case TokenType.Or: case TokenType.GreaterThan: case TokenType.LessThan: return new BuiltInType(ExpressionTypes.Boolean); case TokenType.Infer: return right.AstSymbolType; } if (left.AstSymbolType.ExpressionType != right.AstSymbolType.ExpressionType) { throw new Exception("Mismatched types"); } return left.AstSymbolType; }
public NewAst(Ast name, List<Ast> args) : base(name.Token) { Args = args; Name = name; }
private void Assign(Ast ast, dynamic value, MemorySpace space = null) { if (value is ValueMemory) { var tup = value as ValueMemory; tup.Memory.Assign(ast.Token.TokenValue, tup.Value); return; } if (space != null) { space.Assign(ast.Token.TokenValue, value); return; } MemorySpaces.Current.Assign(ast.Token.TokenValue, value); }
private dynamic Exec(Ast ast) { try { if (ast == null) { return null; } if (ast.ConvertedExpression != null) { return Exec(ast.ConvertedExpression); } switch (ast.AstType) { case AstTypes.ScopeDeclr: ScopeDelcaration(ast as ScopeDeclr); break; case AstTypes.VarDeclr: VariableDeclaration(ast as VarDeclrAst); break; case AstTypes.Expression: var ret = Expression(ast as Expr); if (ret != null) { return ret; } break; case AstTypes.Print: Print(ast as PrintAst); break; case AstTypes.FunctionInvoke: return InvokeFunction(ast as FuncInvoke); case AstTypes.Conditional: ConditionalDo(ast as Conditional); break; case AstTypes.MethodDeclr: var methodDeclr = ast as MethodDeclr; return new MethodSymbol(methodDeclr.Token.TokenValue, ScopeUtil.CreateSymbolType(methodDeclr.ReturnAst), methodDeclr); case AstTypes.While: WhileDo(ast as WhileLoop); break; case AstTypes.Return: ReturnDo(ast as ReturnAst); break; case AstTypes.For: ForDo(ast as ForLoop); break; case AstTypes.Class: ClassDo(ast as ClassAst); break; case AstTypes.ClassRef: return ClassRefDo(ast as ClassReference); break; case AstTypes.New: return NewDo(ast as NewAst); break; } } catch (ReturnException ex) { // let the return value bubble up through all the exectuions until we // get to the source syntax tree that invoked it. at that point safely return the value if (ast.AstType == AstTypes.FunctionInvoke) { return ex.Value; } throw; } return null; }
/// <summary> /// Resolve the target ast type from the current scope, OR give it a scope to use. /// Since things can be resolved in two passes (initial scope and forward reference scope) /// we want to be able to pass in a scope override. The second value is usually only ever used /// on the second pass when determining forward references /// </summary> /// <param name="ast"></param> /// <param name="currentScope"></param> /// <returns></returns> private IType ResolveType(Ast ast, Scope currentScope = null) { var scopeTrys = new List<Scope> { currentScope, ast.CurrentScope }; try { return Current.Resolve(ast).Type; } catch (Exception ex) { try { return ast.CallingScope.Resolve(ast).Type; } catch { foreach (var scopeTry in scopeTrys) { try { if (scopeTry == null) { continue; } var resolvedType = scopeTry.Resolve(ast); var allowedFwdReferences = scopeTry.AllowedForwardReferences(ast); if (allowedFwdReferences || scopeTry.AllowAllForwardReferences || resolvedType is ClassSymbol || resolvedType is MethodSymbol) { return resolvedType.Type; } } catch { } } } } if (ResolvingTypes) { if (ast.IsPureDynamic) { return new BuiltInType(ExpressionTypes.Inferred); } throw new UndefinedElementException(String.Format("Undefined element {0}", ast.Token.TokenValue)); } return null; }
private Symbol Resolve(Ast ast) { return Resolve(ast.Token.TokenValue); }
public ArrayIndexAst(Ast name, Ast index) : base(name.Token) { Name = name; Index = index; }
public Expr(Ast left, Token token, Ast right) : base(token) { Left = left; Right = right; }
public ClassReference(Ast classInstance, List<Ast> deferences) : base(classInstance.Token) { ClassInstance = classInstance; Deferences = deferences; }
public static Symbol DefineUserSymbol(Ast ast, Ast name) { IType type = CreateSymbolType(ast); return new Symbol(name.Token.TokenValue, type); }
private void DefineToScope(Ast ast, Symbol symbol) { if (ast.CurrentScope != null && ast.CurrentScope.Symbols.ContainsKey(symbol.Name)) { Symbol old = ast.CurrentScope.Resolve(symbol.Name); if (old.Type == null) { ast.CurrentScope.Define(symbol); } } Current.Define(symbol); }
public static Symbol DefineUserSymbol(IType type, Ast name) { return new Symbol(name.Token.TokenValue, type); }
private ValueMemory Get(Ast ast) { object item; if (Environment.Count > 0) { foreach (var env in Environment) { item = env.Get(ast.Token.TokenValue, true); if (item != null) { //return item; return new ValueMemory(item, env); } } } item = MemorySpaces.Current.Get(ast.Token.TokenValue); if (item != null) { return new ValueMemory(item, MemorySpaces.Current); } if (ast.CallingMemory != null) { return new ValueMemory(ast.CallingMemory.Get(ast.Token.TokenValue), ast.CallingMemory); } return null; }
public ReturnAst(Ast expression) : base(new Token(TokenType.Return)) { ReturnExpression = expression; }
private Symbol Resolve(Ast ast) { var resolved = ast.CurrentScope.Resolve(ast.Token.TokenValue); if (resolved == null) { resolved = ast.Global.Resolve(ast.Token.TokenValue); if (resolved == null) { var msg = String.Format("Trying to access undefined function {0}", ast.Token.TokenValue); Console.WriteLine(msg); throw new UndefinedElementException(msg); } } return resolved; }
public PrintAst(Ast expression) : base(new Token(TokenType.Print)) { Expression = expression; }
/// <summary> /// Determines user type /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="token"></param> /// <returns></returns> private IType GetExpressionType(Ast left, Ast right, Token token) { switch (token.TokenType) { case TokenType.Ampersand: case TokenType.Or: case TokenType.GreaterThan: case TokenType.Compare: case TokenType.LessThan: case TokenType.NotCompare: return new BuiltInType(ExpressionTypes.Boolean); case TokenType.Method: case TokenType.Infer: if (right is MethodDeclr) { return new BuiltInType(ExpressionTypes.Method, right); } return right.AstSymbolType; } if (!ResolvingTypes && (left.AstSymbolType == null || right.AstSymbolType == null)) { return null; } if (!TokenUtil.EqualOrPromotable(left.AstSymbolType.ExpressionType, right.AstSymbolType.ExpressionType)) { throw new Exception("Mismatched types"); } return left.AstSymbolType; }
public void Start(Ast ast) { ast.Visit(this); }
private void SetScope(Ast ast) { if (ast.CurrentScope == null) { ast.CurrentScope = Current; ast.Global = Global; } if (ast.CurrentScope != null && ast.CurrentScope.Symbols.Count < Current.Symbols.Count) { ast.CurrentScope = Current; } if (ast.Global != null && ast.Global.Symbols.Count < Global.Symbols.Count) { ast.Global = Global; } }