private RuntimeResult VisitVarAccessNode(VarAccessNode node, Context context) { string name = node.Token.Value.ToString(); if (name == "null") { return(new RuntimeResult(new Values.NullValue().SetPositionAndContext(node.Token.Position, context))); } else if (name == "true") { return(new RuntimeResult(new Values.IntegerValue(1, true).SetPositionAndContext(node.Token.Position, context))); } else if (name == "false") { return(new RuntimeResult(new Values.IntegerValue(0, true).SetPositionAndContext(node.Token.Position, context))); } Values.Value value = context.GetSymbol(name); if (value != null) { return(new RuntimeResult(value)); } return(new RuntimeResult(new RuntimeError(node.Token.Position, "Variable '" + name + "' not defined----", context))); }
private RuntimeResult VisitAttributeNode(AttributeNode node, Context context) { RuntimeResult runtimeResult = Visit(node.BaseNode, context); if (runtimeResult.HasError) { return(runtimeResult); } if (node.Node.Type == NodeType.VAR_ASSIGN) { return(VisitVarAssignNode((VarAssignNode)node.Node, runtimeResult.Value.Context, context)); } else if (node.Node.Type == NodeType.CALL) { if (runtimeResult.Value.Type == Values.ValueType.ASSEMBLY) { CallNode callNode = (CallNode)node.Node; Values.AssemblyValue asmVal = (Values.AssemblyValue)runtimeResult.Value; string name = ((VarAccessNode)callNode.Node).Token.Value.ToString(); List <object> args = new List <object>(); for (int i = 0; i < callNode.Arguments.Count; i++) { RuntimeResult result = Visit(callNode.Arguments[i].Item2, context); if (result.HasError) { return(result); } if (result.Value.Type == Values.ValueType.LIST) { object[] array = Util.ListToArray(result.Value); if (array == null) { return(new RuntimeResult(new RuntimeError(callNode.Position, "Error while converting list to an array", context))); } args.Add(array); } else if (result.Value.Type == Values.ValueType.BYTE_ARRAY) { byte[] array = ((Values.ByteArrayValue)result.Value).Bytes.ToArray(); args.Add(array); } else if (result.Value.IsBoolean) { args.Add(result.Value.GetAsBoolean()); } else { args.Add(result.Value.Data); } } return(asmVal.Invoke(name, args.ToArray())); } else if (Util.isPremitiveType(runtimeResult.Value.Type) || runtimeResult.Value.Type == Values.ValueType.C_SHARP) { CallNode callNode = (CallNode)node.Node; List <(string, Values.Value)> args = new List <(string, Values.Value)>(); for (int i = 0; i < callNode.Arguments.Count; i++) { RuntimeResult result = Visit(callNode.Arguments[i].Item2, context); if (result.HasError) { return(result); } args.Add((callNode.Arguments[i].Item1, result.Value)); } string name = ((VarAccessNode)callNode.Node).Token.Value.ToString(); return(runtimeResult.Value.CallMethod(name, args)); } return(VisitCallNode((CallNode)node.Node, runtimeResult.Value.Context, context)); } else if (node.Node.Type == NodeType.VAR_ACCESS) { if (runtimeResult.Value.Type == Values.ValueType.ASSEMBLY || runtimeResult.Value.Type == Values.ValueType.C_SHARP) { VarAccessNode vaccess = (VarAccessNode)node.Node; return(runtimeResult.Value.GetAttribute(vaccess.Token.Value.ToString())); } } return(Visit(node.Node, runtimeResult.Value.Context)); }
private RuntimeResult VisitCallNode(CallNode node, Context context, Context fromCtx = null) { List <(string, Values.Value)> args = new List <(string, Values.Value)>(); for (int i = 0; i < node.Arguments.Count; i++) { RuntimeResult result = Visit(node.Arguments[i].Item2, fromCtx == null ? context : fromCtx); if (result.HasError) { return(result); } args.Add((node.Arguments[i].Item1, result.Value)); } if (node.Node.Type == NodeType.VAR_ACCESS) { VarAccessNode accessNode = (VarAccessNode)node.Node; string name = accessNode.Token.Value.ToString(); if (BuiltinMethods.BuiltinMethodList.ContainsKey(name)) { return(BuiltinMethods.Execute(name, args, node.Position, context)); } else { Values.Value method = context.GetSymbol(name); if (method == null) { return(new RuntimeResult(new RuntimeError(node.Position, "Method '" + name + "' is not defined", context))); } if (method.Type == Values.ValueType.METHOD) { return(((Values.MethodValue)method).Execute(args, this)); } else if (method.Type == Values.ValueType.CLASS) { Values.ClassValue classValue = ((Values.ClassValue)method).Clone(); //classValue.Type = Values.ValueType.OBJECT; if (classValue.BaseClass != null) { RuntimeResult baseResult = classValue.InitializeBaseClass(context, this); if (baseResult.HasError) { return(baseResult); } Context newContext = new Context(name, baseResult.Value.Context); classValue.SetPositionAndContext(accessNode.Token.Position, newContext); newContext.AddSymbol("this", classValue); newContext.AddSymbol("base", baseResult.Value); RuntimeResult runtimeResult = Visit(classValue.Body, newContext); if (runtimeResult.HasError) { return(runtimeResult); } //Constructor Values.Value ctorValue = newContext.GetSymbol("init"); if (ctorValue != null && ctorValue.Type == Values.ValueType.METHOD) { Values.MethodValue initMethod = (Values.MethodValue)ctorValue; RuntimeResult res = initMethod.Execute(args, this); if (res.HasError) { return(res); } } return(new RuntimeResult(classValue)); } else { Context newContext = new Context(name, context); classValue.SetPositionAndContext(accessNode.Token.Position, newContext); newContext.AddSymbol("this", classValue); RuntimeResult runtimeResult = Visit(classValue.Body, newContext); if (runtimeResult.HasError) { return(runtimeResult); } //Constructor Values.Value ctorValue = newContext.GetSymbol("init"); if (ctorValue != null && ctorValue.Type == Values.ValueType.METHOD) { Values.MethodValue initMethod = (Values.MethodValue)ctorValue; initMethod.Execute(args, this); } return(new RuntimeResult(classValue)); } } return(new RuntimeResult(new RuntimeError(node.Position, "'" + name + "' is not a method", context))); } } return(new RuntimeResult(new RuntimeError(node.Position, "Can't call as a method", context))); }