public RuntimeResult InitializeBaseClass(Context ctx, Interpreter interpreter) { if (BaseClass != null) { ClassValue classValue = ((ClassValue)BaseClass).Clone(); if (classValue.BaseClass != null) { RuntimeResult baseResult = classValue.InitializeBaseClass(ctx, interpreter); if (baseResult.HasError) { return(baseResult); } Context newContext = new Context(BaseName, baseResult.Value.Context); classValue.SetPositionAndContext(Position, newContext); newContext.AddSymbol("this", classValue); newContext.AddSymbol("base", baseResult.Value); return(interpreter.Visit(classValue.Body, newContext)); } else { Context newContext = new Context(BaseName, ctx); classValue.SetPositionAndContext(Position, newContext); newContext.AddSymbol("this", classValue); return(interpreter.Visit(classValue.Body, newContext)); } } return(new RuntimeResult(new RuntimeError(Position, "Base class '" + BaseName + "' not found!", ctx))); }
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))); }