private RuntimeResult VisitVarAssignNode(VarAssignNode node, Context context, Context baseCtx = null) { string name = node.Token.Value.ToString(); if (name == "null" || name == "true" || name == "false" || name == "this" || name == "base") { return(new RuntimeResult(new RuntimeError(node.Token.Position, "'" + name + "' is a reserved keyword", context))); } RuntimeResult runtimeResult = Visit(node.Node, baseCtx != null ? baseCtx : context); if (runtimeResult.HasError) { return(runtimeResult); } if (node.TypeToken == null) { if (context.ContainsSymbol(name) && context.GetSymbol(name).TypeDefined) { Values.ValueType toType = context.GetSymbol(name).Type; if (toType != runtimeResult.Value.Type) { Values.Value castedValue = runtimeResult.Value.Cast(toType); if (castedValue == null) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Can't convert '" + runtimeResult.Value.Type.ToString().ToLower() + "' to '" + toType.ToString().ToLower() + "'", context))); } else { context.AddSymbol(name, castedValue); return(runtimeResult); } } } context.AddSymbol(name, runtimeResult.Value); return(runtimeResult); } else { if (node.TypeToken.CheckKeyword("int")) { return(TypeDefAssign(Values.ValueType.INTEGER, runtimeResult.Value, name, node.Token.Position, context)); } if (node.TypeToken.CheckKeyword("complex")) { return(TypeDefAssign(Values.ValueType.COMPLEX, runtimeResult.Value, name, node.Token.Position, context)); } if (node.TypeToken.CheckKeyword("long")) { return(TypeDefAssign(Values.ValueType.INT64, runtimeResult.Value, name, node.Token.Position, context)); } if (node.TypeToken.CheckKeyword("big")) { return(TypeDefAssign(Values.ValueType.BIGINTEGER, runtimeResult.Value, name, node.Token.Position, context)); } } return(new RuntimeResult(new RuntimeError(node.Token.Position, "Type conversion error", context))); }
public void AddSymbol(string name, Values.Value value) { if (symbolTable.ContainsKey(name)) { symbolTable[name] = value; } else { symbolTable.Add(name, value); } }
private RuntimeResult TypeDefAssign(Values.ValueType type, Values.Value from, string name, Position position, Context context) { if (from.Type == type) { context.AddSymbol(name, from); return(new RuntimeResult(from)); } Values.Value castedVal = from.Cast(type); castedVal.TypeDefined = true; if (castedVal == null) { return(new RuntimeResult(new RuntimeError(position, "Can't convert '" + from.Type.ToString().ToLower() + "' to '" + type.ToString().ToLower() + "'", context))); } context.AddSymbol(name, castedVal); return(new RuntimeResult(castedVal)); }
private RuntimeResult VisitWhenNode(WhenNode node, Context context) { Values.Value variable = context.GetSymbol(node.Token.Value.ToString()); if (variable == null) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Variable '" + node.Token.Value + "' not defined", context))); } for (int i = 0; i < node.Cases.Count; i++) { RuntimeResult condResult = Visit(node.Cases[i].Item1, context); if (condResult.HasError) { return(condResult); } if (condResult.Value.Equals(variable).Value.GetAsBoolean()) { return(Visit(node.Cases[i].Item2, context)); } } //if (node.ElseCase != null) // return Visit(node.ElseCase, context); return(new RuntimeResult(new Values.NullValue().SetPositionAndContext(node.Token.Position, context))); }
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 VisitClassNode(ClassNode node, Context context) { string name = node.Token.Value.ToString(); if (node.BaseClassToken != null) { string baseName = node.BaseClassToken.Value.ToString(); Values.Value baseValue = context.GetSymbol(baseName); if (baseValue == null) { return(new RuntimeResult(new RuntimeError(node.BaseClassToken.Position, "Base class '" + baseName + "' not found!", context))); } if (baseValue.Type != Values.ValueType.CLASS) { return(new RuntimeResult(new RuntimeError(node.BaseClassToken.Position, "Object '" + baseName + "' is not a class!", context))); } Values.Value newCls = new Values.ClassValue(name, node.Body, baseValue, baseName).SetPositionAndContext(node.Token.Position, context); context.AddSymbol(name, newCls); return(new RuntimeResult(newCls)); } Values.Value cls = new Values.ClassValue(name, node.Body, null, "").SetPositionAndContext(node.Token.Position, context); context.AddSymbol(name, cls); return(new RuntimeResult(cls)); }
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))); }
public RuntimeResult(Values.Value value) { this.Value = value; }