コード例 #1
0
ファイル: FileLib.cs プロジェクト: henbagle/ME3Explorer
        public async Task <bool> Initialize()
        {
            if (IsInitialized)
            {
                return(true);
            }

            return(await StandardLibrary.InitializeStandardLib() && await Task.Run(() =>
            {
                if (IsInitialized)
                {
                    return true;
                }
                bool success;
                lock (initializationLock)
                {
                    if (IsInitialized)
                    {
                        return true;
                    }

                    success = InternalInitialize();
                    IsInitialized = success;
                    HadInitializationError = !success;
                }

                InitializationStatusChange?.Invoke(true);
                return success;
            }));
        }
コード例 #2
0
ファイル: FileLib.cs プロジェクト: henbagle/ME3Explorer
 private bool InternalInitialize()
 {
     try
     {
         _symbols = StandardLibrary.GetSymbolTable();
         var files     = EntryImporter.GetPossibleAssociatedFiles(Pcc);
         var gameFiles = MELoadedFiles.GetFilesLoadedInGame(Pcc.Game);
         foreach (var fileName in Enumerable.Reverse(files))
         {
             if (gameFiles.TryGetValue(fileName, out string path) && File.Exists(path))
             {
                 using var pcc = MEPackageHandler.OpenMEPackage(path);
                 if (!StandardLibrary.ResolveAllClassesInPackage(pcc, ref _symbols))
                 {
                     return(false);
                 }
             }
         }
         return(StandardLibrary.ResolveAllClassesInPackage(Pcc, ref _symbols));
     }
     catch (Exception e)
     {
         return(false);
     }
 }
コード例 #3
0
ファイル: Program.cs プロジェクト: ealmuina/tiger
        static void GenerateCode(Node root, string outputPath, Scope scope)
        {
            var generator = new CodeGenerator();

            string name      = Path.GetFileNameWithoutExtension(outputPath);
            string filename  = Path.GetFileName(outputPath);
            string directory = Path.GetDirectoryName(outputPath);

            directory = directory == "" ? "./" : directory;

            AssemblyName assemblyName = new AssemblyName(name);

            generator.Assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, directory);
            generator.Module   = generator.Assembly.DefineDynamicModule(name, filename);

            StandardLibrary.Build(generator, scope);

            generator.Type = generator.Module.DefineType("Program");
            MethodBuilder mainMethod = generator.Type.DefineMethod("Main", MethodAttributes.Static, typeof(void), Type.EmptyTypes);

            generator.Assembly.SetEntryPoint(mainMethod);
            generator.Method    = mainMethod;
            generator.Generator = mainMethod.GetILGenerator();

            root.Generate(generator);

            generator.Type.CreateType();
            generator.Module.CreateGlobalFunctions();
            generator.Assembly.Save(filename);
        }
コード例 #4
0
ファイル: CodeGenerator.cs プロジェクト: frankcs/tiger
        public CodeGenerator(string fileName)
        {
            typecount = 0;
            funccount = 0;
            string clearname = Path.GetFileNameWithoutExtension(fileName);

            EXEFileName      = clearname + ".exe";
            ScopedGenerators = new Stack <ILGenerator>();
            AssemblyName assemName = new AssemblyName("TigerProgram");

            ILAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.RunAndSave,
                                                                       Path.GetDirectoryName(fileName));
            ILModule = ILAssembly.DefineDynamicModule(clearname, EXEFileName);

            BuiltInFunctiontoBuilder = new Dictionary <string, MethodBuilder>();

            //Creating the Standard Library
            StandardLibrary = ILModule.DefineType("StandardLibrary", TypeAttributes.Public | TypeAttributes.Class);
            GenerateCodeForBuiltInFunctions();
            StandardLibrary.CreateType();

            //Creating the Program class
            Program    = ILModule.DefineType("Program", TypeAttributes.Public | TypeAttributes.Class);
            EntryPoint = Program.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static);
            ILAssembly.SetEntryPoint(EntryPoint);
            EnterGenerationScope(EntryPoint.GetILGenerator());
        }
コード例 #5
0
 public static StandardLibrary Instance()
 {
     if (_stdlib == null)
     {
         _stdlib = new StandardLibrary();
     }
     return(_stdlib);
 }
コード例 #6
0
        public RootScope(Context context)
        {
            _context   = context;
            _functions = new FunctionCollection();
            _variables = new VariableCollection();
            _classes   = new ClassCollection();
            _objects   = new ObjectCollection();
            _arrays    = new ArrayCollection();

            StandardLibrary.Populate(_functions);
            StandardLibrary.Populate(_variables);
        }
コード例 #7
0
        public static Function CompileFunctionBodyAST(ExportEntry parentExport, string scriptText, Function func, MessageLog log, FileLib lib = null)
        {
            var symbols = lib?.GetSymbolTable() ?? StandardLibrary.GetSymbolTable();

            symbols.RevertToObjectStack();

            if (parentExport.IsClass && symbols.TryGetType(parentExport.ObjectName, out Class containingClass))
            {
                int      funcIdx          = containingClass.Functions.FindIndex(fun => fun.Name == func.Name);
                Function originalFunction = containingClass.Functions[funcIdx];
                originalFunction.Body       = func.Body;
                originalFunction.Body.Outer = originalFunction;
                for (int i = 0; i < func.Parameters.Count && i < originalFunction.Parameters.Count; i++)
                {
                    originalFunction.Parameters[i].UnparsedDefaultParam = func.Parameters[i].UnparsedDefaultParam;
                }
                originalFunction.Locals.Clear();

                if (!containingClass.Name.CaseInsensitiveEquals("Object"))
                {
                    symbols.GoDirectlyToStack(((Class)containingClass.Parent).GetInheritanceString());
                    symbols.PushScope(containingClass.Name);
                }

                CodeBodyParser.ParseFunction(originalFunction, scriptText, symbols, log);
                return(originalFunction);
            }
            //in state
            if (parentExport.Parent is ExportEntry classExport && classExport.IsClass && symbols.TryGetType(classExport.ObjectNameString, out Class cls) &&
                cls.States.FirstOrDefault(s => s.Name.CaseInsensitiveEquals(parentExport.ObjectNameString)) is State state &&
                state.Functions.FirstOrDefault(f => f.Name == func.Name) is Function canonicalFunction)
            {
                canonicalFunction.Body       = func.Body;
                canonicalFunction.Body.Outer = canonicalFunction;
                for (int i = 0; i < func.Parameters.Count && i < canonicalFunction.Parameters.Count; i++)
                {
                    canonicalFunction.Parameters[i].UnparsedDefaultParam = func.Parameters[i].UnparsedDefaultParam;
                }
                canonicalFunction.Locals.Clear();

                symbols.GoDirectlyToStack(((Class)cls.Parent).GetInheritanceString());
                symbols.PushScope(cls.Name);
                symbols.PushScope(state.Name);

                CodeBodyParser.ParseFunction(canonicalFunction, scriptText, symbols, log);
                return(canonicalFunction);
            }

            return(null);
        }
コード例 #8
0
ファイル: CodeGenerator.cs プロジェクト: frankcs/tiger
 /// <summary>
 /// Generate a function in the StandardLibrary
 /// </summary>
 /// <param name="returntype"></param>
 /// <param name="parameters"></param>
 /// <returns></returns>
 private MethodBuilder CreateSTDFunction(Type returntype, Type[] parameters)
 {
     return(StandardLibrary.DefineMethod(GetNewFunctionName(), MethodAttributes.Public | MethodAttributes.Static,
                                         returntype, parameters));
 }
コード例 #9
0
        public static void BuildTigerProgram(string output, InstructionNode programExp)
        {
            string fileName = Path.GetFileNameWithoutExtension(output);
            string exeName  = fileName + ".exe";
            //Definimos el nombre del ensamblado
            AssemblyName assemblyName = new AssemblyName(fileName);

            //Creamos un assemblyBuilder con el nombre del ensamblado deseado y en modo save
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetDirectoryName(output));
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(fileName, exeName);
            TypeBuilder     typeBuilder     = moduleBuilder.DefineType("TigerProgram", TypeAttributes.Public | TypeAttributes.Class);
            MethodBuilder   methodBuilder   = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]);


            StandardLibrary stdlib = new StandardLibrary(moduleBuilder);
            ILGenerator     gen    = methodBuilder.GetILGenerator();

            ILCodeGenerator cg = new ILCodeGenerator(moduleBuilder, typeBuilder, gen, stdlib);


            var result = gen.DeclareLocal(typeof(int));

            //asigno 0 a result
            gen.Emit(OpCodes.Ldc_I4_0);
            gen.Emit(OpCodes.Stloc, result);

            // Begin the try block.
            gen.BeginExceptionBlock();

            programExp.GenCode(cg);
            if (!(programExp.ReturnType is VoidType))//saco el resultado de la pila
            {
                gen.Emit(OpCodes.Pop);
            }

            // Start the catch block for any Exception
            gen.BeginCatchBlock(typeof(Exception));
            PropertyInfo message    = typeof(Exception).GetProperty("Message");
            MethodInfo   getMessage = message.GetGetMethod();

            gen.Emit(OpCodes.Callvirt, getMessage);
            MethodInfo writeLine = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });

            gen.Emit(OpCodes.Call, writeLine);
            MethodInfo readLine = typeof(Console).GetMethod("ReadLine");

            gen.Emit(OpCodes.Call, readLine);
            gen.Emit(OpCodes.Pop);

            //pongo 1 en result
            gen.Emit(OpCodes.Ldc_I4_1);
            gen.Emit(OpCodes.Stloc, result);

            gen.EndExceptionBlock();

            //en result estara el codigo de salida
            gen.Emit(OpCodes.Ldloc, result);
            gen.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            assemblyBuilder.SetEntryPoint(methodBuilder);
            assemblyBuilder.Save(exeName);
        }
コード例 #10
0
        static void Main(string[] args)
        {
            Lexer         lexer         = new Lexer();
            Session       session       = new Session();
            CodeGenerator codeGenerator = new CodeGenerator(session);

            //Add the standard library
            StandardLibrary.AddStandardLibrary(codeGenerator);

            while (true)
            {
                try
                {
                    string input  = Console.ReadLine();
                    var    tokens = lexer.Tokenize(input);

                    Parser parser = new Parser(tokens, session.BinaryOperatorPrecedence);

                    foreach (var currentTree in parser.Parse())
                    {
                        currentTree.GenerateCode(codeGenerator, SyntaxTreeGeneratorData.Empty);

                        if (currentTree is FunctionSyntaxTree)
                        {
                            FunctionSyntaxTree funcTree = (FunctionSyntaxTree)currentTree;

                            if (funcTree.Prototype.Name != "")
                            {
                                Console.WriteLine("Defined function '" + funcTree.Prototype.Name + "'");
                            }
                        }

                        if (currentTree is ExternalFunctionSyntaxTree)
                        {
                            ExternalFunctionSyntaxTree funcTree = (ExternalFunctionSyntaxTree)currentTree;

                            if (funcTree.Prototype.Name != "")
                            {
                                Console.WriteLine("Defined external function '" + funcTree.Prototype.Name + "' referencing: " + funcTree.FuncReference);
                            }
                        }
                    }

                    if (codeGenerator.Methods.ContainsKey("main"))
                    {
                        var mainMethod = codeGenerator.Methods["main"];
                        mainMethod.Invoke(null, null);
                    }
                }
                catch (ParserException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (CodeGeneratorException e)
                {
                    Console.WriteLine(e.Message);
                }

                codeGenerator.Methods.Remove("main");
            }
        }
コード例 #11
0
        public Evaluator(Parser interpreter)
        {
            p = interpreter;
            interpreter.evaluator = this;

            var includeStatement = new Operation("include")
            {
                canBeGlobal   = true,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    List <string> toInclude = new List <string>();
                    p.Eat("l curly");
                    while (p.CurrentToken != "r curly")
                    {
                        toInclude.Add(p.GetIdentifier().ToLower());
                        if (p.CurrentToken != "r curly")
                        {
                            p.Eat("comma");
                        }
                    }
                    p.Eat();

                    /*toInclude.Reverse();
                     *
                     * Lexer.inputText = Lexer.inputText.Substring(Lexer.pointer);
                     * Lexer.pointer = 0;
                     * foreach (var file in toInclude)
                     * {
                     *  Lexer.inputText = System.IO.File.ReadAllText(file + ".hpy") + "\n" + Lexer.inputText;
                     * }
                     *
                     * p.lastLexerPoint = 0;
                     * p.PreviousToken = null;
                     * p.CurrentToken = Lexer.GetNextToken();*/

                    return(Value.VOID);
                }
            };

            var functionDeclaration = new Operation("function")
            {
                canBeGlobal   = true,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    if (p.depth > 0)
                    {
                        throw p.Exception("Can only declare a function in the global scope");
                    }

                    if (p.CurrentToken == "inline")
                    {
                        p.Eat();
                    }

                    string name = p.GetIdentifier();

                    List <string>          argNames = new List <string>();
                    List <Value.BatchType> argTypes = new List <Value.BatchType>();

                    p.Eat("l bracket");
                    while (p.CurrentToken != "r bracket")
                    {
                        argNames.Add(p.Eat <string>("identifier"));
                        p.Eat("colon");
                        argTypes.Add(Value.ParseType(p.GetIdentifier()));

                        if (p.CurrentToken != "r bracket")
                        {
                            p.Eat("comma");
                        }
                    }
                    p.Eat();

                    Value.BatchType returnType = Value.BatchType.Void;
                    if (p.CurrentToken == "colon")
                    {
                        p.Eat("colon");
                        returnType = Value.ParseType(p.GetIdentifier());
                    }

                    var func = UserFunctions.Get(name, argTypes);
                    int id   = UserFunctions.GetID(func);

                    Variables.suffix = "_F" + id;

                    int    index          = p.output.Length;
                    string originalOutput = p.output;

                    if (func.inline)
                    {
                        for (int i = 0; i < argNames.Count; i++)
                        {
                            Variables.Create(argNames[i] + "_I" + id, argTypes[i]);
                        }
                    }
                    else
                    {
                        p.Comment("BEGIN FUNCTION DECLARATION: " + UserFunctions.GetSignature(name, argTypes) + ": " + returnType.ToString().ToLower());
                        p.output += ":func_" + id + "\n";
                        for (int i = 0; i < argNames.Count; i++)
                        {
                            Variables.Create(argNames[i], new Value(argTypes[i], "%~" + (i + 1)), 1);
                        }
                    }

                    currentContext = func;

                    p.EvaluateBlock();

                    currentContext = null;

                    if (!func.inline)
                    {
                        if (!p.output.Trim().EndsWith("goto :EOF"))
                        {
                            //Variables.variables.Exists(x => false);
                            Variables.DeleteOutOfScopeVariables();
                            p.output += "goto :EOF\n";
                        }
                    }

                    //p.Comment("END FUNCTION DECLARATION");

                    if (UserFunctions.IsRecursive(func, func))
                    {
                        throw p.Exception("Recursion is forbidden");
                    }

                    Variables.suffix = "";

                    string newOutput = p.output;
                    p.output = originalOutput;
                    string code = newOutput.Substring(index);

                    func.body = code;

                    return(Value.VOID);
                }
            };

            var variableDeclaration = new Operation("var")
            {
                canBeGlobal   = true,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    int depth = p.depth;

                    string name;
                    Value  val;

                    if (depth == 0)
                    {
                        if (p.CurrentToken == "global")
                        {
                            p.Eat();
                        }

                        name = p.Eat <string>("identifier");
                        var v = Variables.Get(name);
                        p.Eat("colon");
                        var type = Value.ParseType(p.GetIdentifier());

                        if (p.CurrentToken == "equals")
                        {
                            p.Eat();
                            val = Evaluate();

                            if (type != val.type)
                            {
                                throw p.Exception("Attempt to assign value of type " + val.type + " to a variable of type " + type);
                            }

                            Variables.Assign(name, val);
                        }

                        return(Value.VOID);
                    }

                    if (p.CurrentToken == "global")
                    {
                        p.Eat();
                        depth = 0;
                    }

                    name = p.Eat <string>("identifier");

                    if (Variables.variables.Exists(x => x.name == name))
                    {
                        //throw p.Exception("Variable already exists in this scope: " + name);
                    }

                    if (p.CurrentToken == "colon")
                    {
                        p.Eat();
                        var type = Value.ParseType(p.GetIdentifier());

                        if (Value.TypeEquals(type, Value.BatchType.Void))
                        {
                            throw p.Exception("Cannot declare a variable of type Void");
                        }

                        if (p.CurrentToken != "equals")
                        {
                            Variables.Create(name, type, depth);
                            return(Value.VOID);
                        }

                        p.Eat("equals");
                        val = Evaluate();

                        if (type != val.type)
                        {
                            throw p.Exception("Attempt to assign value of type " + val.type + " to a variable of type " + type);
                        }

                        Variables.Create(name, val, depth);
                    }
                    else
                    {
                        if (depth == 0)
                        {
                            throw p.Exception("Variables in the global scope must have their types specified");
                        }

                        p.Eat("equals");
                        val = Evaluate();

                        if (Value.TypeEquals(val.type, Value.BatchType.Void))
                        {
                            throw p.Exception("Cannot declare a variable of type Void");
                        }

                        if (depth > 0)
                        {
                            Variables.Create(name, val, depth);
                        }
                    }

                    return(Value.VOID);
                }
            };

            var numberLiteral = new Operation("number")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) => new Value(Value.BatchType.Int, p.Eat <float>().ToString())
            };

            var stringLiteral = new Operation("string")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) => new Value(Value.BatchType.String, p.Eat <string>())
            };

            var boolLiteral = new Operation("bool")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) => new Value(Value.BatchType.Bool, p.Eat <bool>() ? "1==1" : "1==0")
            };

            var bracket = new Operation("l bracket")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) => {
                    var outp = Evaluate();
                    p.Eat("r bracket");

                    if (outp.type == Value.BatchType.Int)
                    {
                        return(new Value(Value.BatchType.Int, "(" + outp.value + ")"));
                    }

                    var temp = Variables.CreateTemporary(outp.value);
                    return(new Value(outp.type, temp));
                }
            };

            var neg = new Operation("minus")
            {
                association   = Operation.Association.Right,
                unaryFunction = (right) => new Value(Value.BatchType.Int, "-" + right)
            };

            var mul = new Operation("multiply")
            {
                binaryFunction = (left, right) => binaryOp(left, right, Value.BatchType.Int, "*")
            };

            var div = new Operation("divide")
            {
                binaryFunction = (left, right) => binaryOp(left, right, Value.BatchType.Int, "/")
            };

            var mod = new Operation("modulus")
            {
                binaryFunction = (left, right) => binaryOp(left, right, Value.BatchType.Int, "%%")
            };

            var add = new Operation("plus")
            {
                binaryFunction = (left, right) => binaryOp(left, right, Value.BatchType.Int, "+")
            };

            var concat = new Operation("concat")
            {
                binaryFunction = (left, right) => new Value(Value.BatchType.String, left.value + right.value)
            };

            var sub = new Operation("minus")
            {
                binaryFunction = (left, right) => binaryOp(left, right, Value.BatchType.Int, "-")
            };



            var identifier = new Operation("identifier")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    string name = p.Eat <string>("identifier").ToString();

                    if (StandardLibrary.Exists(name))
                    {
                        List <Value> args = new List <Value>();
                        p.Eat("l bracket");
                        while (p.CurrentToken != "r bracket")
                        {
                            args.Add(Evaluate());
                            if (p.CurrentToken != "r bracket")
                            {
                                p.Eat("comma");
                            }
                        }
                        p.Eat();
                        return(StandardLibrary.CallFunction(name, args.ToArray()));
                    }
                    else
                    {
                        if (p.CurrentToken == "l bracket")
                        {
                            p.Comment("FUNCTION CALL TO " + name);

                            List <Value> args = new List <Value>();
                            p.Eat("l bracket");
                            while (p.CurrentToken != "r bracket")
                            {
                                args.Add(Evaluate());
                                if (p.CurrentToken != "r bracket")
                                {
                                    p.Eat("comma");
                                }
                            }
                            p.Eat();

                            var func = UserFunctions.Get(name, args.Select(x => x.type).ToList());
                            int id   = UserFunctions.GetID(func);

                            currentContext?.calls.Add(func);

                            if (func.inline)
                            {
                                for (int i = 0; i < func.argumentNames.Count; i++)
                                {
                                    Variables.Create(func.argumentNames[i] + "_I" + id, args[i]);
                                }

                                p.output += func.body;

                                for (int i = 0; i < func.argumentNames.Count; i++)
                                {
                                    Variables.Delete(func.argumentNames[i] + "_I" + id);
                                }
                            }
                            else
                            {
                                p.output += "call :func_" + id + " " +
                                            string.Join(" ", args.Select(x =>
                                                                         (x.type == Value.BatchType.String && x.value.Contains(" ")) ? "\"" + x.value + "\"" : x.value)) + "\n";
                            }

                            if (func.returnType == Value.BatchType.Void)
                            {
                                p.Comment("END FUNCTION CALL");
                                return(Value.VOID);
                            }
                            else
                            {
                                //string temp = Variables.CreateTemporary("%return_value%");
                                p.Comment("END FUNCTION CALL");
                                return(new Value(func.returnType, "%return_value%"));
                            }
                        }

                        if (p.CurrentToken == "increment")
                        {
                            p.Eat();
                            Variables.VerifyType(name, Value.BatchType.Int);
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "+=1\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "decrement")
                        {
                            p.Eat();
                            Variables.VerifyType(name, Value.BatchType.Int);
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "-=1\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "add")
                        {
                            p.Eat();
                            var v  = Evaluate();
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "+=" + v.value + "\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "subtract")
                        {
                            p.Eat();
                            var v  = Evaluate();
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "-=" + v.value + "\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "string add")
                        {
                            p.Eat();
                            var v  = Evaluate();
                            var va = Variables.Get(name);
                            p.output += "set var_" + name + (va.depth > 0 ? Variables.suffix : "") + "=!var_" + name + Variables.suffix + "!" + v.value + "\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "inc mul")
                        {
                            p.Eat();
                            var v  = Evaluate();
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "*=" + v.value + "\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "inc div")
                        {
                            p.Eat();
                            var v  = Evaluate();
                            var va = Variables.Get(name);
                            p.output += "set /a var_" + name + (va.depth > 0 ? Variables.suffix : "") + "/=" + v.value + "\n";
                            return(Value.VOID);
                        }
                        else if (p.CurrentToken == "equals")
                        {
                            p.Eat();
                            var v = Evaluate();

                            if (!Variables.Exists(name) && !name.Contains("%"))
                            {
                                throw p.Exception("No such variable exists: " + name);
                            }

                            Variables.Assign(name, v);
                            return(Value.VOID);
                        }
                        else
                        {
                            if (name.Contains("%"))
                            {
                                //var temp1 = Variables.CreateTemporary("var_" + name);
                                //var temp2 = Variables.CreateTemporary("");
                                //var temp2name = Variables.NameFromTempReference(temp2);
                                //p.EmitLn("call set " + temp2name + "=%%" + temp1 + "%%");
                                return(new Value(Value.BatchType.Indeterminate, "!var_" + name + "!"));
                            }
                            else
                            {
                                //return Variables.GetReference(name);
                                if (currentContext != null && currentContext.inline)
                                {
                                    return(Variables.GetReference(name + "_I" + UserFunctions.GetID(currentContext)));
                                }
                                else
                                {
                                    return(Variables.GetReference(name));
                                }
                            }
                            //return Variables.GetReference(name);
                        }
                    }
                }
            };

            var openBracket = new Operation("l curly")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    p.Eat();
                    return(new Value(Value.BatchType.Void, ""));
                }
            };

            var closeBracket = new Operation("r curly")
            {
                eatOperator   = false,
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    p.Eat();
                    return(new Value(Value.BatchType.Void, ""));
                }
            };

            var ifStatement = new Operation("if")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    int selfid = ++ifid;

                    var condition = EvaluateCondition();

                    string output = "";

                    string temp = Variables.CreateTemporary(condition.value);

                    output += "if " + temp + " (\n";
                    output += "goto if_" + selfid + "\n";
                    output += ")";

                    string ifContents = p.PreEvaluateBlock();

                    List <string> elseIfContents = new List <string>();
                    int           elseifs        = 0;
                    while (p.CurrentToken == "elseif")
                    {
                        elseifs++;
                        p.Eat();
                        condition = EvaluateCondition();
                        temp      = Variables.CreateTemporary(condition.value);

                        output += " else (\nif " + temp + " (\n";
                        output += "goto if_" + selfid + "_elseif_" + elseifs + "\n";
                        output += ")";

                        elseIfContents.Add(p.PreEvaluateBlock());
                    }

                    string elseContents = null;
                    if (p.CurrentToken == "else")
                    {
                        p.Eat();
                        output += " else (\n";
                        output += "goto if_" + selfid + "_else\n";
                        output += ")";

                        elseContents = p.PreEvaluateBlock();
                    }

                    for (int i = 0; i < elseifs; i++)
                    {
                        output += "\n)";
                    }

                    output += "\ngoto if_" + selfid + "_end";

                    output += "\n:if_" + selfid + "\n";
                    output += ifContents;
                    output += "goto if_" + selfid + "_end\n";

                    for (int i = 1; i <= elseifs; i++)
                    {
                        output += ":if_" + selfid + "_elseif_" + i + "\n";
                        output += elseIfContents[i - 1];
                        output += "goto if_" + selfid + "_end\n";
                    }

                    if (elseContents != null)
                    {
                        output += ":if_" + selfid + "_else\n";
                        output += elseContents;
                    }

                    output += ":if_" + selfid + "_end\n";

                    p.output += output;

                    return(new Value(Value.BatchType.Void, ""));
                }
            };

            var whileLoop = new Operation("while")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    int loop = ++loopid;

                    p.output += ":loop_" + loop + "\n";

                    var condition = EvaluateCondition();
                    var temp      = Variables.CreateTemporary(condition.value);

                    p.output += "if not " + temp + " goto loop_" + loop + "_end\n";

                    p.loopIDs.Push(loop);

                    p.EvaluateBlock();

                    p.loopIDs.Pop();

                    p.output += "goto loop_" + loop + "\n";
                    p.output += ":loop_" + loop + "_end";

                    return(new Value(Value.BatchType.Void, ""));
                }
            };

            var untilLoop = new Operation("until")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    int loop = ++loopid;

                    p.output += ":loop_" + loop + "\n";

                    var condition = EvaluateCondition();
                    var temp      = Variables.CreateTemporary(condition.value);

                    p.output += "if " + temp + " goto loop_" + loop + "_end\n";

                    p.loopIDs.Push(loop);

                    p.EvaluateBlock();

                    p.loopIDs.Pop();

                    p.output += "goto loop_" + loop + "\n";
                    p.output += ":loop_" + loop + "_end";


                    return(new Value(Value.BatchType.Void, ""));
                }
            };

            void VerifyType(Value v, Value.BatchType type)
            {
                if (v.type != type)
                {
                    throw p.Exception("Expected value of type " + type + ", not " + v.type);
                }
            }

            var forLoop = new Operation("from")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    var start = Evaluate();
                    VerifyType(start, Value.BatchType.Int);

                    p.Eat("to");
                    var end = Evaluate();
                    VerifyType(end, Value.BatchType.Int);

                    bool upwards;
                    try
                    {
                        upwards = int.Parse(start.value) < int.Parse(end.value);
                    }
                    catch
                    {
                        upwards = true;
                    }

                    Value step;
                    if (p.CurrentToken == "by")
                    {
                        p.Eat();
                        step = Evaluate();
                        VerifyType(step, Value.BatchType.Int);
                    }
                    else
                    {
                        step = new Value(Value.BatchType.Int, upwards ? "1" : "-1");
                    }

                    bool usingVariable = p.CurrentToken == "with";

                    string name      = null;
                    string reference = null;

                    if (usingVariable)
                    {
                        p.Eat();
                        string varname = p.Eat <string>();

                        reference = Variables.Create(varname, start, p.depth).value; // %var_x%
                        name      = "var_" + varname;                                // var_x
                    }
                    else
                    {
                        reference = Variables.CreateTemporaryInt(start.value);  // %temp_x%
                        name      = Variables.NameFromTempReference(reference); // temp_x
                    }

                    int loop = ++loopid;
                    p.output += ":loop" + loop + "\n";

                    p.output += "if not " + reference + " " + (upwards ? "LSS" : "GTR") + " " + end.value + " goto loop" + loop + "_end\n";

                    p.EvaluateBlock();

                    p.loopIDs.Pop();

                    p.output += "set /a " + name + (usingVariable ? Variables.suffix : "") + "+=" + step.value + "\n";
                    p.output += "goto loop" + loop + "\n";
                    p.output += ":loop" + loop + "_end\n";

                    if (usingVariable)
                    {
                        Variables.Delete(Variables.NameFromReference(reference));
                    }

                    return(Value.VOID);
                }
            };

            var continueStatement = new Operation("continue")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    return(new Value(Value.BatchType.Void, "goto loop" + p.loopIDs.Peek()));
                }
            };

            var breakStatement = new Operation("break")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    return(new Value(Value.BatchType.Void, "goto loop" + p.loopIDs.Peek() + "_end"));
                }
            };

            var not = new Operation("not")
            {
                association   = Operation.Association.Right,
                unaryFunction = (right) => new Value(Value.BatchType.Bool, "not " + right)
            };

            Value BoolOp(Value left, Value right, string op)
            {
                var tempL      = Variables.FlexibleTemporary(left);
                var tempR      = Variables.FlexibleTemporary(right);
                var tempResult = Variables.CreateTemporary("1==0");
                var name       = Variables.NameFromTempReference(tempResult);

                p.EmitLn("if " + tempL + " " + op + " " + tempR + " set " + name + "=1==1");
                return(new Value(Value.BatchType.Bool, tempResult));
            }

            Value IntComparisonOp(Value left, Value right, string op)
            {
                VerifyType(left, Value.BatchType.Int);
                VerifyType(right, Value.BatchType.Int);
                return(BoolOp(left, right, op));
            }

            var eq = new Operation("double equal")
            {
                binaryFunction = (left, right) => BoolOp(left, right, "EQU")
            };

            var neq = new Operation("not equal")
            {
                binaryFunction = (left, right) => BoolOp(left, right, "NEQ")
            };

            var gr = new Operation("greater than")
            {
                binaryFunction = (left, right) => IntComparisonOp(left, right, "GTR")
            };

            var ls = new Operation("less than")
            {
                binaryFunction = (left, right) => IntComparisonOp(left, right, "LSS")
            };

            var geq = new Operation("greater or equal")
            {
                binaryFunction = (left, right) => IntComparisonOp(left, right, "GEQ")
            };

            var leq = new Operation("less or equal")
            {
                binaryFunction = (left, right) => IntComparisonOp(left, right, "LEQ")
            };

            var semicolon = new Operation("semicolon")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    return(Value.VOID);
                }
            };

            var and = new Operation("and")
            {
                binaryFunction = (left, right) =>
                {
                    string reference = Variables.CreateTemporary("1==0");
                    string name      = Variables.NameFromTempReference(reference);
                    //p.output += NewTempBoolVar("1==0");
                    //int id = varid;
                    p.output += "if " + left.value + " ( if " + right.value + " ( \n";
                    p.output += "set " + name + "=1==1\n";
                    p.output += ") \n)\n";

                    return(new Value(Value.BatchType.Bool, reference));
                }
            };

            var or = new Operation("or")
            {
                binaryFunction = (left, right) =>
                {
                    string reference = Variables.CreateTemporary("1==0");
                    string name      = Variables.NameFromTempReference(reference);
                    //p.output += NewTempBoolVar("1==1");
                    //int id = varid;
                    p.output += "if " + left.value + " set " + name + "=1==1\n";
                    p.output += "if " + right.value + " set " + name + "=1==1\n";
                    return(new Value(Value.BatchType.Bool, reference));
                }
            };

            /*
             * var arrayLiteral = new Operation("l square")
             * {
             *  association = Operation.Association.None,
             *  unaryFunction = (none) =>
             *  {
             *      string array = "";
             *      while(p.CurrentToken != "r square")
             *      {
             *          array += Evaluate() + " ";
             *
             *          if (p.CurrentToken != "r square")
             *          {
             *              p.Eat("comma");
             *          }
             *      }
             *      p.Eat();
             *
             *      return new Value(Value.BatchType.Array, array.TrimEnd());
             *  }
             * };*/

            var returnStatement = new Operation("return")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    if (currentContext == null)
                    {
                        throw p.Exception("Can only return a value from within a function");
                    }

                    Value v;

                    if (p.CurrentToken == "semicolon")
                    {
                        v = Value.VOID;
                    }
                    else
                    {
                        v         = Evaluate();
                        p.output += "set " + (v.type == Value.BatchType.Int ? "/a " : "") + "\"return_value=" + v.value + "\"\n";
                    }

                    if (currentContext.returnType != v.type)
                    {
                        throw p.Exception("Must return value of type " + currentContext.returnType + ", not " + v.type);
                    }

                    //returnValueType = v.type;
                    int depth = p.depth;
                    p.depth = 0;
                    Variables.DeleteOutOfScopeVariables();
                    p.depth = depth;

                    /*foreach (var name in variablesDeclaredInsideFunction)
                     * {
                     *  name.de
                     * }*/

                    return(new Value(Value.BatchType.Void, currentContext.inline ? "" : "goto :EOF"));
                }
            };

            var referenceOf = new Operation("ampersand")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    var name = p.GetIdentifier();
                    if (name.Contains("%"))
                    {
                        return(new Value(Value.BatchType.String, name));
                    }

                    var val = Variables.Get(name);
                    return(new Value(Value.BatchType.String, name + (val.depth > 0 ? Variables.suffix : "")));
                }
            };

            var deleteStatement = new Operation("delete")
            {
                association   = Operation.Association.None,
                unaryFunction = (none) =>
                {
                    var var = p.GetIdentifier();
                    Variables.Delete(var, true);
                    return(Value.VOID);
                }
            };

            var asStatement = new Operation("as")
            {
                association   = Operation.Association.Left,
                unaryFunction = (left) =>
                {
                    VerifyType(left, Value.BatchType.Indeterminate);
                    return(new Value(Value.ParseType(p.GetIdentifier()), left.value));
                }
            };

            void register(Operation op)
            {
                precedences.Last().Add(op);
            }

            void precedence()
            {
                precedences.Add(new List <Operation>());
            }

            precedence();
            register(semicolon);

            precedence();
            register(referenceOf);
            //register(toStringLiteral);
            //register(thisLiteral);
            //register(baseLiteral);
            register(bracket);
            //register(undefinedLiteral);
            //register(arrayLiteral);
            register(numberLiteral);
            register(stringLiteral);
            register(boolLiteral);
            //register(tableLiteral);
            //register(charLiteral);
            ////register(instantiation);

            precedence();
            register(identifier);
            //register(methodCall);
            //register(traverse);
            //register(index);

            precedence();
            register(asStatement);

            precedence();
            register(variableDeclaration);

            precedence();
            register(neg);
            register(not);

            //precedence();
            //register(pow);

            precedence();
            register(mul);
            register(div);
            register(mod);

            precedence();
            register(concat);
            register(add);
            register(sub);

            precedence();
            register(eq);
            register(neq);
            register(gr);
            register(ls);
            register(geq);
            register(leq);

            precedence();
            register(and);

            precedence();
            register(or);

            //precedence();
            //register(conditional);

            precedence();
            register(closeBracket);
            register(openBracket);
            register(ifStatement);
            register(whileLoop);
            register(untilLoop);
            //register(includeStatement);
            //register(forEachLoop);
            register(continueStatement);
            register(breakStatement);
            register(functionDeclaration);
            //register(funcLiteral);
            register(returnStatement);
            register(deleteStatement);
            register(forLoop);
            //register(structureLiteral);
            //register(include);
            //register(tryCatch);
            //register(throwStatement);
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: lexakogut/lexCalculator
        static void Main(string[] args)
        {
            CalculationContext userContext = new CalculationContext();

            userContext.AssignContext(StandardLibrary.GenerateStandardContext());

            /*
             * FinishedFunction length2d = linker.BuildFunction(constructor.Construct(tokenizer.Tokenize(
             *      "sqrt(x^2 + y^2)")), userContext, new string[] {
             *      "x", "y" });
             * userContext.FunctionTable.AssignItem("length2d", length2d);
             * userContext.FunctionTable.AssignItem("length3d", linker.BuildFunction(constructor.Construct(tokenizer.Tokenize(
             *      "sqrt(x^2 + y^2 + z^2)")), userContext, new string[] {
             *      "x", "y", "z" }));
             * userContext.FunctionTable.AssignItem("distance2d", linker.BuildFunction(constructor.Construct(tokenizer.Tokenize(
             *      "length2d(x2 - x1, y2 - y1)")), userContext, new string[] {
             *      "x1", "y1", "x2", "y2" }));
             * userContext.FunctionTable.AssignItem("distance3d", linker.BuildFunction(constructor.Construct(tokenizer.Tokenize(
             *      "length3d(x2 - x1, y2 - y1, z2 - z1)")), userContext, new string[] {
             *      "x1", "y1", "z1", "x2", "y2", "z2" }));
             */

            while (true)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write("> ");
                string input = Console.ReadLine();
                Console.ResetColor();

                try
                {
                    if (String.IsNullOrEmpty(input))
                    {
                        continue;
                    }

                    if (input.StartsWith("~"))
                    {
                        if (input.StartsWith("~help"))
                        {
                            Console.WriteLine("Try those inputs: ");
                            Console.ForegroundColor = ConsoleColor.Gray;
                            Console.WriteLine("2 + 2");
                            Console.WriteLine("f(x) = e^x");
                            Console.WriteLine("myVar = f(4)");
                            Console.ResetColor();

                            void printCommand(string name, string desc, string[] parameters)
                            {
                                Console.ForegroundColor = ConsoleColor.Cyan;
                                Console.Write("~{0}", name);
                                Console.ForegroundColor = ConsoleColor.Yellow;
                                for (int i = 0; i < parameters.Length; ++i)
                                {
                                    Console.Write(" [{0}]", parameters[i]);
                                }
                                Console.ResetColor();
                                Console.Write(" - ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.WriteLine(desc);
                                Console.ResetColor();
                            }

                            Console.WriteLine();
                            Console.WriteLine("List of commands: ");
                            printCommand("help", "this command", new string[0]);
                            printCommand("summary", "prints what functions does your library have", new string[0]);
                            printCommand("library", "prints all trees of all functions in your library", new string[0]);
                            printCommand("lexer", "divides expression into tokens, that's all", new string[] { "expr" });
                            printCommand("tree", "prints function tree", new string[] { "func" });
                            printCommand("test", "test function with random parameters for correctness and effectiveness", new string[] { "func" });
                            printCommand("optimize", "look how your function can be optimized", new string[] { "func" });
                            printCommand("dx", "find differential with respect to 1st parameter", new string[] { "func" });
                            printCommand("dy", "find differential with respect to 2nd parameter", new string[] { "func" });
                            printCommand("dz", "find differential with respect to 3rd parameter", new string[] { "func" });
                            continue;
                        }

                        if (input.StartsWith("~summary"))
                        {
                            PrintLibrarySummary(userContext);
                            continue;
                        }

                        if (input.StartsWith("~library"))
                        {
                            PrintLibrary(userContext);
                            continue;
                        }

                        if (input.StartsWith("~tree "))
                        {
                            string funcName = input.Substring(6).Trim(' ');
                            visualizer.VisualizeAsTree(userContext.FunctionTable[funcName].TopNode, userContext);
                            continue;
                        }

                        if (input.StartsWith("~lexer "))
                        {
                            string  expression = input.Substring(7).Trim(' ');
                            Token[] tokens     = lexer.Tokenize(expression);
                            Console.Write("Tokens: [ ");
                            foreach (Token token in tokens)
                            {
                                switch (token)
                                {
                                case NumberToken _: Console.ForegroundColor = ConsoleColor.White; break;

                                case SymbolToken _: Console.ForegroundColor = ConsoleColor.Yellow; break;

                                case IdentifierToken _: Console.ForegroundColor = ConsoleColor.Cyan; break;
                                }
                                Console.Write("{0} ", token.ToString());
                                Console.ResetColor();
                            }
                            Console.WriteLine("]\n");
                            continue;
                        }

                        if (input.StartsWith("~test "))
                        {
                            TestInput(input, userContext);
                            continue;
                        }

                        if (input.StartsWith("~dx "))
                        {
                            FindDifferentialInput(input, 0, userContext);
                            continue;
                        }

                        if (input.StartsWith("~dy "))
                        {
                            FindDifferentialInput(input, 1, userContext);
                            continue;
                        }

                        if (input.StartsWith("~dz "))
                        {
                            FindDifferentialInput(input, 2, userContext);
                            continue;
                        }

                        if (input.StartsWith("~optimize "))
                        {
                            OptimizeInput(input, userContext);
                            continue;
                        }

                        throw new Exception("Unknown command");
                    }

                    string   expressionString = input;
                    TreeNode firstHalfTree    = null;
                    int      equalsPos        = input.IndexOf('=');
                    if (equalsPos > 0)
                    {
                        expressionString = input.Substring(equalsPos + 1);
                        string identifierString = input.Substring(0, equalsPos);

                        Token[] firstHalfTokens = lexer.Tokenize(identifierString);
                        firstHalfTree = parser.Construct(firstHalfTokens);

                        switch (firstHalfTree)
                        {
                        case UndefinedFunctionTreeNode fDefinition:
                            DefineFunctionInput(fDefinition, expressionString, userContext);
                            break;

                        case UndefinedVariableTreeNode vDefinition:
                            DefineVariableInput(vDefinition, expressionString, userContext);
                            break;

                        default: throw new Exception("Unknown syntax");
                        }
                    }
                    else
                    {
                        CalculateInput(input, userContext);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(String.Format("Error: {0}", ex.Message));
                }
                Console.WriteLine();
            }
        }
コード例 #13
0
        protected GameContext(IGraphicsPlugin graphics, IInputPlugin input, IAudioPlugin audio,
                              ITimerPlugin timer, IResourceContext predefinedResources)
        {
            Timer    = timer;
            Graphics = graphics;
            Input    = input;
            Audio    = audio;

            var sprites = predefinedResources.GetPredefinedSprites(this);

            Sprites = new IndexedResourceManager <GameSprite>(sprites);

            var sounds = predefinedResources.GetPredefinedSounds(this);

            Sounds = new IndexedResourceManager <GameSound>(sounds);

            var backgrounds = predefinedResources.GetPredefinedBackgrounds(this);

            Backgrounds = new IndexedResourceManager <GameBackground>(backgrounds);

            var fonts = predefinedResources.GetPredefinedFonts(this);

            Fonts = new IndexedResourceManager <GameFont>(fonts);

            var paths = predefinedResources.GetPredefinedPaths(this);

            Paths = new IndexedResourceManager <GamePath>(paths);

            var scripts = predefinedResources.GetPredefinedScripts(this);

            Scripts = new IndexedResourceManager <GameScript>(scripts);

            var timelines = predefinedResources.GetPredefinedTimelines(this);

            Timelines = new IndexedResourceManager <GameTimeline>(timelines);

            var objects = predefinedResources.GetPredefinedObjects(this);

            Objects = new IndexedResourceManager <GameObject>(objects);
            foreach (var gameObject in Objects)
            {
                gameObject.OnRegisterEvents();
            }

            Instances = new IndexedResourceManager <IInstance>(100001);

            var rooms = predefinedResources.GetPredefinedRooms(this);

            Rooms     = new IndexedResourceManager <GameRoom>(rooms);
            RoomOrder = rooms.Select(r => r.Id).ToList();

            var triggers = predefinedResources.GetPredefinedTriggers(this);

            Triggers = new IndexedResourceManager <ITrigger>(triggers);

            Instances.SetNextIndex(predefinedResources.NextInstanceId);
            Sprites.SetNextIndex(predefinedResources.NextSpriteId);
            Objects.SetNextIndex(predefinedResources.NextObjectId);
            Rooms.SetNextIndex(predefinedResources.NextRoomId);

            Graphics.Load  += Graphics_Load;
            Graphics.Draw  += Graphics_Update;
            Input.KeyPress += Input_KeyPress;

            Library = new StandardLibrary(this);

            Init();
        }