Пример #1
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            BlockNode result = new BlockNode();

            // Iterating indices (and not values via foreach)
            // to avoid crashes occuring with AddToPool within AddToPool

            for (int i = 0; i < p.Pool.Lines.Count; ++i)
            {
                Pool.PooledLine line = p.Pool.Lines[i];

                MergeableGenerator <Token> tempGenerator = new MergeableGenerator <Token>(line.Tokens);
                tempGenerator.MoveNext();

                while (!tempGenerator.EOS)
                {
                    p.ParseLine(tempGenerator, line.Scope).IfJust(
                        (lineNode) => result.Children.Add(lineNode));
                }
            }

            p.Pool.Lines.Clear();

            return(new Just <ILineNode>(result));
        }
Пример #2
0
        private static Maybe <IList <Token> > TokenizeParam(EAParser p, IParamNode param)
        {
            switch (param.Type)
            {
            case ParamType.STRING:
                Token     input = ((StringNode)param).MyToken;
                Tokenizer t     = new Tokenizer();
                return(new Just <IList <Token> >(new List <Token>(t.TokenizeLine(input.Content, input.FileName, input.LineNumber, input.ColumnNumber))));

            case ParamType.MACRO:
                try
                {
                    IList <Token> myBody = new List <Token>(((MacroInvocationNode)param).ExpandMacro());
                    return(new Just <IList <Token> >(myBody));
                }
                catch (KeyNotFoundException)
                {
                    MacroInvocationNode asMacro = (MacroInvocationNode)param;
                    p.Error(asMacro.MyLocation, "Undefined macro: " + asMacro.Name);
                }
                break;

            case ParamType.LIST:
                ListNode n = (ListNode)param;
                return(new Just <IList <Token> >(new List <Token>(n.ToTokens())));

            case ParamType.ATOM:
                return(new Just <IList <Token> >(new List <Token>(((IAtomNode)param).ToTokens())));
            }
            return(new Nothing <IList <Token> >());
        }
Пример #3
0
 public MacroInvocationNode(EAParser p, Token invokeTok, IList <IList <Token> > parameters, ImmutableStack <Closure> scopes)
 {
     this.p           = p;
     this.invokeToken = invokeTok;
     this.Parameters  = parameters;
     this.scope       = scopes;
 }
Пример #4
0
        public Maybe <ILineNode> HandleDirective(EAParser p, Token directive, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            string directiveName = directive.Content.Substring(1);

            if (directives.TryGetValue(directiveName, out IDirective? toExec))
            {
                if (!toExec.RequireInclusion || p.IsIncluding)
                {
                    if (toExec.MinParams <= parameters.Count && (!toExec.MaxParams.HasValue || parameters.Count <= toExec.MaxParams))
                    {
                        return(toExec.Execute(p, directive, parameters, tokens));
                    }
                    else
                    {
                        p.Error(directive.Location, "Invalid number of parameters (" + parameters.Count + ") to directive " + directiveName + ".");
                    }
                }
            }
            else
            {
                p.Error(directive.Location, "Directive not recognized: " + directiveName);
            }

            return(new Nothing <ILineNode>());
        }
Пример #5
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            Maybe <string> existantFile = FileSearcher.FindFile(Path.GetDirectoryName(self.FileName), parameters[0].ToString());

            if (!existantFile.IsNothing)
            {
                try
                {
                    string pathname = existantFile.FromJust;

                    FileStream inputFile        = new FileStream(pathname, FileMode.Open);
                    Tokenizer  newFileTokenizer = new Tokenizer();
                    tokens.PrependEnumerator(newFileTokenizer.Tokenize(inputFile).GetEnumerator());
                }
                catch (Exception)
                {
                    p.Error(self.Location, "Error reading file \"" + parameters[0].ToString() + "\".");
                }
            }
            else
            {
                p.Error(parameters[0].MyLocation, "Could not find file \"" + parameters[0].ToString() + "\".");
            }
            return(new Nothing <ILineNode>());
        }
Пример #6
0
        public MacroCollection(EAParser parent)
        {
            Macros = new Dictionary <string, Dictionary <int, IMacro> >();
            Parent = parent;

            BuiltInMacros = new Dictionary <string, BuiltInMacro> {
                { "String", new String() },
                { "IsDefined", new IsDefined(parent) },
                { "AddToPool", new AddToPool(parent) },
            };
        }
Пример #7
0
        private static IEnumerable <Token> ExpandAllIdentifiers(EAParser p, Queue <Token> tokens, ImmutableStack <string> seenDefs, ImmutableStack <Tuple <string, int> > seenMacros)
        {
            IEnumerable <Token> output = new List <Token>();

            while (tokens.Count > 0)
            {
                Token current = tokens.Dequeue();
                if (current.Type == TokenType.IDENTIFIER)
                {
                    if (p.Macros.ContainsName(current.Content) && tokens.Count > 0 && tokens.Peek().Type == TokenType.OPEN_PAREN)
                    {
                        IList <IList <Token> > param = p.ParseMacroParamList(new MergeableGenerator <Token>(tokens)); //TODO: I don't like wrapping this in a mergeable generator..... Maybe interface the original better?
                        if (!seenMacros.Contains(new Tuple <string, int>(current.Content, param.Count)) && p.Macros.HasMacro(current.Content, param.Count))
                        {
                            foreach (Token t in  p.Macros.GetMacro(current.Content, param.Count).ApplyMacro(current, param, p.GlobalScope))
                            {
                                yield return(t);
                            }
                        }
                        else if (seenMacros.Contains(new Tuple <string, int>(current.Content, param.Count)))
                        {
                            yield return(current);

                            foreach (IList <Token> l in param)
                            {
                                foreach (Token t in l)
                                {
                                    yield return(t);
                                }
                            }
                        }
                        else
                        {
                            yield return(current);
                        }
                    }
                    else if (!seenDefs.Contains(current.Content) && p.Definitions.ContainsKey(current.Content))
                    {
                        foreach (Token t in p.Definitions[current.Content].ApplyDefinition(current))
                        {
                            yield return(t);
                        }
                    }
                    else
                    {
                        yield return(current);
                    }
                }
                else
                {
                    yield return(current);
                }
            }
        }
Пример #8
0
 public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
 {
     if (p.Inclusion.IsEmpty)
     {
         p.Error(self.Location, "No matching if[n]def.");
     }
     else
     {
         p.Inclusion = p.Inclusion.Tail;
     }
     return(new Nothing <ILineNode>());
 }
Пример #9
0
        public EAInterpreter(IOutput output, string game, string rawsFolder, string rawsExtension, Stream sin, string inFileName, Log log)
        {
            this.game   = game;
            this.output = output;

            try
            {
                allRaws = ProcessRaws(game, ListAllRaws(rawsFolder, rawsExtension));
            }
            catch (RawReader.RawParseException e)
            {
                Location loc = new Location
                {
                    file    = e.FileName,
                    lineNum = e.LineNumber,
                    colNum  = 1
                };

                log.Message(Log.MsgKind.ERROR, loc, "An error occured while parsing raws");
                log.Message(Log.MsgKind.ERROR, loc, e.Message);

                Environment.Exit(-1); // ew?
            }

            this.sin = sin;
            this.log = log;
            iFile    = inFileName;

            IncludeFileSearcher includeSearcher = new IncludeFileSearcher();

            includeSearcher.IncludeDirectories.Add(AppDomain.CurrentDomain.BaseDirectory);

            foreach (string path in EAOptions.Instance.includePaths)
            {
                includeSearcher.IncludeDirectories.Add(path);
            }

            IncludeFileSearcher toolSearcher = new IncludeFileSearcher {
                AllowRelativeInclude = false
            };

            toolSearcher.IncludeDirectories.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tools"));

            foreach (string path in EAOptions.Instance.toolsPaths)
            {
                includeSearcher.IncludeDirectories.Add(path);
            }

            myParser = new EAParser(allRaws, log, new Preprocessor.DirectiveHandler(includeSearcher, toolSearcher));

            myParser.Definitions['_' + game + '_']  = new Definition();
            myParser.Definitions["__COLORZ_CORE__"] = new Definition();
        }
Пример #10
0
 public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
 {
     foreach (IParamNode parm in parameters)
     {
         string s = parm.ToString();
         if (p.Definitions.ContainsKey(s))
         {
             p.Definitions.Remove(parm.ToString());
         }
         else
         {
             p.Warning(parm.MyLocation, "Undefining non-existant definition: " + s);
         }
     }
     return(new Nothing <ILineNode>());
 }
Пример #11
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            bool           flag = true;
            Maybe <string> identifier;

            foreach (IParamNode parameter in parameters)
            {
                if (parameter.Type == ParamType.ATOM && !(identifier = ((IAtomNode)parameter).GetIdentifier()).IsNothing)
                {
                    flag &= p.Macros.ContainsName(identifier.FromJust) || p.Definitions.ContainsKey(identifier.FromJust); //TODO: Built in definitions?
                }
                else
                {
                    p.Error(parameter.MyLocation, "Definition name must be an identifier.");
                }
            }
            p.Inclusion = new ImmutableStack <bool>(flag, p.Inclusion);
            return(new Nothing <ILineNode>());
        }
Пример #12
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            Maybe <string> existantFile = FileSearcher.FindFile(Path.GetDirectoryName(self.FileName), parameters[0].ToString() !);

            if (!existantFile.IsNothing)
            {
                try
                {
                    string pathname = existantFile.FromJust;
                    return(new Just <ILineNode>(new DataNode(p.CurrentOffset, File.ReadAllBytes(pathname))));
                }
                catch (Exception)
                {
                    p.Error(self.Location, "Error reading file \"" + parameters[0].ToString() + "\".");
                }
            }
            else
            {
                p.Error(parameters[0].MyLocation, "Could not find file \"" + parameters[0].ToString() + "\".");
            }
            return(new Nothing <ILineNode>());
        }
Пример #13
0
        public Maybe <ILineNode> Execute(EAParser parse, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            ExecTimer.Timer.AddTimingPoint(ExecTimer.KEY_GENERIC);

            Maybe <string> validFile = FileSearcher.FindFile(Path.GetDirectoryName(self.FileName), IOUtility.GetToolFileName(parameters[0].ToString() !));

            if (validFile.IsNothing)
            {
                parse.Error(parameters[0].MyLocation, "Tool " + parameters[0].ToString() + " not found.");
                return(new Nothing <ILineNode>());
            }
            //TODO: abstract out all this running stuff into a method so I don't have code duplication with inctext

            //from http://stackoverflow.com/a/206347/1644720
            // Start the child process.
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.RedirectStandardError = true;
            // Redirect the output stream of the child process.
            p.StartInfo.WorkingDirectory       = Path.GetDirectoryName(self.FileName) !;
            p.StartInfo.UseShellExecute        = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow         = true;
            p.StartInfo.FileName = validFile.FromJust;
            StringBuilder argumentBuilder = new StringBuilder();

            for (int i = 1; i < parameters.Count; i++)
            {
                if (parameters[i].Type == ParamType.ATOM)
                {
                    parameters[i] = ((IAtomNode)parameters[i]).Simplify();
                }
                argumentBuilder.Append(parameters[i].PrettyPrint());
                argumentBuilder.Append(' ');
            }
            argumentBuilder.Append("--to-stdout");
            p.StartInfo.Arguments = argumentBuilder.ToString();
            p.Start();
            // Do not wait for the child process to exit before
            // reading to the end of its redirected stream.
            // p.WaitForExit();
            // Read the output stream first and then wait.
            MemoryStream outputBytes = new MemoryStream();
            MemoryStream errorStream = new MemoryStream();

            p.StandardOutput.BaseStream.CopyTo(outputBytes);
            p.StandardError.BaseStream.CopyTo(errorStream);
            p.WaitForExit();

            byte[] output = outputBytes.GetBuffer().Take((int)outputBytes.Length).ToArray();
            if (errorStream.Length > 0)
            {
                parse.Error(self.Location, Encoding.ASCII.GetString(errorStream.GetBuffer().Take((int)errorStream.Length).ToArray()));
            }
            else if (output.Length >= 7 && Encoding.ASCII.GetString(output.Take(7).ToArray()) == "ERROR: ")
            {
                parse.Error(self.Location, Encoding.ASCII.GetString(output.Skip(7).ToArray()));
            }

            ExecTimer.Timer.AddTimingPoint(parameters[0].ToString() !.ToLower());

            return(new Just <ILineNode>(new DataNode(parse.CurrentOffset, output)));
        }
Пример #14
0
 public AddToPool(EAParser parent)
 {
     ParentParser = parent;
 }
Пример #15
0
 public BaseClosure(EAParser enclosing)
 {
     this.enclosing = enclosing;
 }
Пример #16
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            if (parameters[0].Type == ParamType.MACRO)
            {
                MacroInvocationNode signature = (MacroInvocationNode)(parameters[0]);
                string        name            = signature.Name;
                IList <Token> myParams        = new List <Token>();
                foreach (IList <Token> l1 in signature.Parameters)
                {
                    if (l1.Count != 1 || l1[0].Type != TokenType.IDENTIFIER)
                    {
                        p.Error(l1[0].Location, "Macro parameters must be identifiers (got " + l1[0].Content + ").");
                    }
                    else
                    {
                        myParams.Add(l1[0]);
                    }
                }

                /* if (!p.IsValidMacroName(name, myParams.Count))
                 * {
                 *  if (p.IsReservedName(name))
                 *  {
                 *      p.Error(signature.MyLocation, "Invalid redefinition: " + name);
                 *  }
                 *  else
                 *      p.Warning(signature.MyLocation, "Redefining " + name + '.');
                 * }*/
                if (p.Macros.HasMacro(name, myParams.Count))
                {
                    p.Warning(signature.MyLocation, "Redefining " + name + '.');
                }
                Maybe <IList <Token> > toRepl;
                if (parameters.Count != 2)
                {
                    toRepl = new Just <IList <Token> >(new List <Token>());
                }
                else
                {
                    toRepl = ExpandParam(p, parameters[1], myParams.Select((Token t) => t.Content));
                }
                if (!toRepl.IsNothing)
                {
                    p.Macros.AddMacro(new Macro(myParams, toRepl.FromJust), name, myParams.Count);
                }
            }
            else
            {
                //Note [mutually] recursive definitions are handled by Parser expansion.
                Maybe <string> maybeIdentifier;
                if (parameters[0].Type == ParamType.ATOM && !(maybeIdentifier = ((IAtomNode)parameters[0]).GetIdentifier()).IsNothing)
                {
                    string name = maybeIdentifier.FromJust;
                    if (p.Definitions.ContainsKey(name))
                    {
                        p.Warning(parameters[0].MyLocation, "Redefining " + name + '.');
                    }
                    if (parameters.Count == 2)
                    {
                        Maybe <IList <Token> > toRepl = ExpandParam(p, parameters[1], Enumerable.Empty <string>());
                        if (!toRepl.IsNothing)
                        {
                            p.Definitions[name] = new Definition(toRepl.FromJust);
                        }
                    }
                    else
                    {
                        p.Definitions[name] = new Definition();
                    }
                }
                else
                {
                    p.Error(parameters[0].MyLocation, "Definition names must be identifiers (got " + parameters[0].ToString() + ").");
                }
            }
            return(new Nothing <ILineNode>());
        }
Пример #17
0
        public Maybe <ILineNode> Execute(EAParser parse, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            ExecTimer.Timer.AddTimingPoint(ExecTimer.KEY_GENERIC);

            Maybe <string> validFile = FileSearcher.FindFile(Path.GetDirectoryName(self.FileName), IOUtility.GetToolFileName(parameters[0].ToString()));

            if (validFile.IsNothing)
            {
                parse.Error(parameters[0].MyLocation, "Tool " + parameters[0].ToString() + " not found.");
                return(new Nothing <ILineNode>());
            }

            //from http://stackoverflow.com/a/206347/1644720
            // Start the child process.
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.RedirectStandardError = true;
            // Redirect the output stream of the child process.
            p.StartInfo.WorkingDirectory       = Path.GetDirectoryName(self.FileName);
            p.StartInfo.UseShellExecute        = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow         = true;
            p.StartInfo.FileName = validFile.FromJust;
            StringBuilder argumentBuilder = new StringBuilder();

            for (int i = 1; i < parameters.Count; i++)
            {
                parameters[i].AsAtom().IfJust((IAtomNode n) => { parameters[i] = n.Simplify(); });
                argumentBuilder.Append(parameters[i].PrettyPrint());
                argumentBuilder.Append(' ');
            }
            argumentBuilder.Append("--to-stdout");
            p.StartInfo.Arguments = argumentBuilder.ToString();
            p.Start();
            // Do not wait for the child process to exit before
            // reading to the end of its redirected stream.
            // p.WaitForExit();
            // Read the output stream first and then wait.
            MemoryStream outputBytes = new MemoryStream();
            MemoryStream errorStream = new MemoryStream();

            p.StandardOutput.BaseStream.CopyTo(outputBytes);
            p.StandardError.BaseStream.CopyTo(errorStream);
            p.WaitForExit();

            byte[] output = outputBytes.GetBuffer().Take((int)outputBytes.Length).ToArray();
            if (errorStream.Length > 0)
            {
                parse.Error(self.Location, Encoding.ASCII.GetString(errorStream.GetBuffer().Take((int)errorStream.Length).ToArray()));
            }
            else if (output.Length >= 7 && Encoding.ASCII.GetString(output.Take(7).ToArray()) == "ERROR: ")
            {
                parse.Error(self.Location, Encoding.ASCII.GetString(output.Skip(7).ToArray()));
            }
            else
            {
                outputBytes.Position = 0; //Reset MemoryStream position so StreamReader starts reading from beginning.
                Tokenizer t = new Tokenizer();
                tokens.PrependEnumerator(t.Tokenize(outputBytes, Path.GetFileName(self.FileName) + ", Line " + self.LineNumber + "; " + parameters[0].ToString()).GetEnumerator());
            }

            ExecTimer.Timer.AddTimingPoint(parameters[0].ToString().ToLower());

            return(new Nothing <ILineNode>());
        }
Пример #18
0
 public IsDefined(EAParser parent)
 {
     ParentParser = parent;
 }