private void VariableDeclaration(VarDeclrAst varDeclrAst) { if (varDeclrAst.VariableValue == null) { var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue); var space = MemorySpaces.Current; space.Define(symbol.Name, TokenType.Nil); return; } var variableValue = varDeclrAst.VariableValue.ConvertedExpression ?? varDeclrAst.VariableValue; // if the rhs of a variable is not a method, then execute it, if (variableValue.AstType != AstTypes.MethodDeclr) { var value = GetValue(Exec(variableValue)); if (value != null) { var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue); var space = MemorySpaces.Current; if (variableValue.IsLink) { space.Link(symbol.Name, variableValue.Token.TokenValue); } else { space.Define(symbol.Name, value); } } } else { var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue); var resolvedMethod = varDeclrAst.CurrentScope.Resolve(variableValue.Token.TokenValue) as MethodSymbol; // make sure to create a NEW method symbol. this way each time we declare this item // it will create a local copy and get its own memory space for closures. // if we shared the same method symbol then all instances of the same declaration would share the memory space, // which may not be what we want given class instances having their own spaces var localMethodCopy = new MethodSymbol(resolvedMethod.Name, resolvedMethod.Type, resolvedMethod.MethodDeclr); var space = MemorySpaces.Current; if (variableValue is LambdaDeclr) { localMethodCopy.Environment = space; } space.Define(symbol.Name, localMethodCopy); } }
private LambdaDeclr CreateCurriedMethod(FuncInvoke ast, MethodSymbol functionType) { var srcMethod = functionType.MethodDeclr; var fixedAssignments = new List <VarDeclrAst>(); var count = 0; foreach (var argValue in ast.Arguments) { var srcArg = srcMethod.Arguments[count] as VarDeclrAst; var token = new Token(srcArg.DeclarationType.Token.TokenType, argValue.Token.TokenValue); var declr = new VarDeclrAst(token, srcArg.Token, new Expr(argValue.Token)); // if we're creating a curry using a variable then we need to resolve the variable type // otherwise we can make a symbol for the literal var newArgType = argValue.Token.TokenType == TokenType.Word ? ast.CurrentScope.Resolve(argValue).Type : ScopeUtil.CreateSymbolType(argValue); // create a symbol type for the target we're invoking on so we can do type checking var targetArgType = ScopeUtil.CreateSymbolType(srcArg.DeclarationType); if (!TokenUtil.EqualOrPromotable(newArgType, targetArgType)) { throw new InvalidSyntax(String.Format("Cannot pass argument {0} of type {1} to partial function {2} as argument {3} of type {4}", argValue.Token.TokenValue, newArgType.TypeName, srcMethod.MethodName.Token.TokenValue, srcArg.VariableName.Token.TokenValue, targetArgType.TypeName)); } fixedAssignments.Add(declr); count++; } var newBody = fixedAssignments.Concat(srcMethod.Body.ScopedStatements).ToList(); var curriedMethod = new LambdaDeclr(srcMethod.Arguments.Skip(ast.Arguments.Count).ToList(), new ScopeDeclr(newBody)); SetScope(curriedMethod); return(curriedMethod); }
public void Visit(VarDeclrAst ast) { if (ast.DeclarationType != null) { ast.DeclarationType.Visit(this); } ast.VariableName.Visit(this); if (ast.VariableValue != null) { Console.WriteLine("Equals"); ast.VariableValue.Visit(this); } }
public void Visit(VarDeclrAst ast) { Exec(ast); }
public void Visit(VarDeclrAst ast) { var isVar = ast.DeclarationType.Token.TokenType == TokenType.Infer; if (ast.DeclarationType != null && !isVar) { var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName); symbol.IsArray = ast is ArrayDeclrAst; DefineToScope(ast, symbol); ast.AstSymbolType = symbol.Type; } if (ast.VariableValue == null && isVar) { var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName); DefineToScope(ast, symbol); ast.AstSymbolType = symbol.Type; } else if (ast.VariableValue != null) { ast.VariableValue.Visit(this); // if its type inferred, determine the declaration by the value's type if (isVar) { // if the right hand side is a method declaration, make sure to track the source value // this way we can reference it later to determine not only that this is a method type, but what // is the expected return value for static type checking later var val = ast.VariableValue.ConvertedExpression ?? ast.VariableValue; ast.AstSymbolType = val is MethodDeclr ? new BuiltInType(ExpressionTypes.Method, val) : val.AstSymbolType; var symbol = ScopeUtil.DefineUserSymbol(ast.AstSymbolType, ast.VariableName); symbol.IsArray = ast is ArrayDeclrAst; DefineToScope(ast, symbol); } else if (ResolvingTypes) { var declaredType = ScopeUtil.CreateSymbolType(ast.DeclarationType); var value = ast.VariableValue.ConvertedExpression ?? ast.VariableValue; ReturnAst returnType = null; // when we're resolving types check if the rhs is a function invoke. if it is, see // what the return value of the src expression is so we can make sure that the // lhs and the rhs match. try { returnType = value is FuncInvoke ? ((value as FuncInvoke).AstSymbolType) != null ? ((value as FuncInvoke).AstSymbolType.Src as MethodDeclr).ReturnAst : null : null; } catch { } value = returnType != null ? returnType.ReturnExpression : value; if (!TokenUtil.EqualOrPromotable(value.AstSymbolType.ExpressionType, declaredType.ExpressionType)) { throw new InvalidSyntax(String.Format("Cannot assign {0} of type {1} to {2}", ast.VariableValue, value.AstSymbolType.ExpressionType, declaredType.ExpressionType)); } } } SetScope(ast); }