Пример #1
0
        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)));
        }
Пример #2
0
 public void AddSymbol(string name, Values.Value value)
 {
     if (symbolTable.ContainsKey(name))
     {
         symbolTable[name] = value;
     }
     else
     {
         symbolTable.Add(name, value);
     }
 }
Пример #3
0
 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));
 }
Пример #4
0
 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)));
 }
Пример #5
0
        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)));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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)));
        }
Пример #8
0
 public RuntimeResult(Values.Value value)
 {
     this.Value = value;
 }