Пример #1
0
        public virtual bool VisitRepeatStatement(RepeatStatement statement)
        {
            VisitNode(statement.ConditionExp);
            VisitNodes(statement.Statements);

            return(true);
        }
Пример #2
0
 public virtual TReturn Visit(RepeatStatement node, TParam param)
 {
     node.Limit.Accept(this, param);
     node.Counter.Accept(this, param);
     node.Body.ForEach(stmt => stmt.Accept(this, param));
     return(DefaultReturn);
 }
Пример #3
0
        public override void VisitChildren(IVisitor visitor)
        {
            InitialStatement.Visit(visitor);
            Condition.Visit(visitor);
            RepeatStatement.Visit(visitor);

            Body.Visit(visitor);
        }
Пример #4
0
        public override void VisitRepeatStatement(RepeatStatement repeatStatement)
        {
            scopes_.Push(scopes_.Peek().CreateChildScope(repeatStatement));

            base.VisitRepeatStatement(repeatStatement);

            scopes_.Pop();

        }
Пример #5
0
 public override void ConstructRepeatStatement(RepeatStatement node)
 {
     this.WriteIndented("repeat");
     this.Indent( );
     this.ConstructStatementList(node.Body);
     this.Outdent( );
     this.WriteIndented("until ");
     this.ConstructInternal(node.Condition);
     if (node.HasSemicolon)
     {
         this.Write(';');
     }
 }
Пример #6
0
            public override void VisitRepeatStatement(RepeatStatement node)
            {
                // reduce REPEAT statement to a WHILE statement

                /* REPEAT n i
                 *    block
                 * ENDREPEAT
                 *
                 * i = 0
                 * WHILE i < n
                 *    block
                 *    i = i + 1
                 * ENDWHILE
                 */

                var boundLimit   = Bind(node.Limit) !;
                var boundCounter = Bind(node.Counter) !;

                // i = 0
                var zeroCounter = new BoundAssignmentStatement(boundCounter, new BoundIntLiteralExpression(0));

                stmts !.Add(zeroCounter);

                // WHILE i < n
                var condition  = new BoundBinaryExpression(boundCounter, boundLimit, BinaryOperator.Less);
                var boundWhile = new BoundWhileStatement(condition);

                stmts !.Add(boundWhile);

                VisitScope(node.Block, boundWhile.Block);

                // i = i + 1
                var add    = new BoundBinaryExpression(boundCounter, new BoundIntLiteralExpression(1), BinaryOperator.Add);
                var assign = new BoundAssignmentStatement(boundCounter, add);

                boundWhile.Block.Add(assign);
            }
Пример #7
0
 public virtual TReturn Visit(RepeatStatement node, TParam param) => throw new NotImplementedException();
Пример #8
0
 protected virtual Object[] AnalyseRepeatStatement(RepeatStatement node, params Object[] args)
 {
     this.Analyse(node.Body);
     this.Analyse(node.Condition);
     return(null);
 }
Пример #9
0
        public override object VisitAsmline(Z80AsmParser.AsmlineContext context)
        {
            CurrentLabel      = null;
            CurrentLabelColon = false;
            CurrentComment    = null;
            LabelSpan         = null;
            KeywordSpan       = null;
            CommentSpan       = null;
            IssueToEmit       = null;
            IsFieldAssignment = false;
            NumberSpans       = null;
            IdentifierSpans   = null;
            StringSpans       = null;
            FunctionSpans     = null;
            SemiVarSpans      = null;
            MacroParamSpans   = null;
            MacroParamNames   = null;
            SemiVarSpans      = null;
            StatementSpans    = null;
            OperandSpans      = null;
            MnemonicSpans     = null;

            if (context?.Start == null || context.Stop == null)
            {
                return(null);
            }

            var startIndex = context.start.StartIndex;
            var stopIndex  = context.stop.StopIndex;

            CurrentSourceText = InputStream.GetText(new Interval(startIndex, stopIndex));

            CurrentSourceLine = context.Start.Line;
            FirstColumn       = context.Start.Column;
            FirstPosition     = context.Start.StartIndex;
            LastPosition      = context.Stop.StopIndex;

            object mainInstructionPart = null;

            // --- Obtain label
            var labelCtx = context.label();

            if (labelCtx != null)
            {
                CurrentLabel      = labelCtx.GetChild(0).NormalizeToken();
                CurrentLabelColon = labelCtx.COLON() != null;
                LabelSpan         = new TextSpan(labelCtx.Start.StartIndex, labelCtx.Start.StopIndex + 1);
            }

            // --- Obtain line body/directive
            var lineBodyCtx = context.lineBody();

            if (lineBodyCtx != null)
            {
                // --- Special case, when a macro parameters is used as the main line
                LastInstructionPos = lineBodyCtx.Stop.StopIndex;
                var macroParamCtx = lineBodyCtx.macroParam();
                if (macroParamCtx != null)
                {
                    VisitMacroParam(macroParamCtx);
                    mainInstructionPart = new MacroParamLine(macroParamCtx.IDENTIFIER()?.NormalizeToken());
                }
                else
                {
                    mainInstructionPart = VisitLineBody(context.lineBody());
                }
            }
            else if (context.directive() != null)
            {
                mainInstructionPart = VisitDirective(context.directive());
            }

            // --- Obtain comment
            if (context.comment() != null)
            {
                var commentCtx = context.comment();
                CurrentComment = commentCtx.GetText();
                CommentSpan    = new TextSpan(commentCtx.Start.StartIndex, commentCtx.Stop.StopIndex + 1);
            }

            // --- Now, we have every part of the line, and create some special main instruction part
            if (context.exception != null)
            {
                mainInstructionPart = new ParserErrorLine();
            }
            else if (mainInstructionPart == null && (CurrentLabel != null || CurrentComment != null))
            {
                mainInstructionPart = new NoInstructionLine();
                if (CurrentLabel != null && !CurrentLabelColon)
                {
                    var statementFound = true;
                    switch (CurrentLabel.ToLower())
                    {
                    case "continue":
                        mainInstructionPart = new ContinueStatement();
                        break;

                    case "break":
                        mainInstructionPart = new BreakStatement();
                        break;

                    case "endm":
                    case "mend":
                        mainInstructionPart = new MacroEndStatement();
                        break;

                    case "endl":
                    case "lend":
                        mainInstructionPart = new LoopEndStatement();
                        break;

                    case "proc":
                        mainInstructionPart = new ProcStatement();
                        break;

                    case "endp":
                    case "pend":
                        mainInstructionPart = new ProcEndStatement();
                        break;

                    case "repeat":
                        mainInstructionPart = new RepeatStatement();
                        break;

                    case "endw":
                    case "wend":
                        mainInstructionPart = new WhileEndStatement();
                        break;

                    case "ends":
                        mainInstructionPart = new StructEndStatement();
                        break;

                    case "else":
                        mainInstructionPart = new ElseStatement();
                        break;

                    case "endif":
                        mainInstructionPart = new IfEndStatement();
                        break;

                    default:
                        statementFound = false;
                        break;
                    }

                    if (statementFound)
                    {
                        KeywordSpan  = new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1);
                        CurrentLabel = null;
                    }
                }
            }

            return(mainInstructionPart is SourceLineBase sourceLine
                ? AddLine(sourceLine, context)
                : mainInstructionPart);
        }
Пример #10
0
        static List <CompletionItem> DoStatement(Statement s)
        {
            List <CompletionItem> ret = new List <CompletionItem>();

            if (s is AssignmentStatement && !(s is AugmentedAssignmentStatement))
            {
                AssignmentStatement a = s as AssignmentStatement;
                foreach (Expression e in a.Lhs)
                {
                    ret.AddRange(DoExpr(e));
                }
                foreach (Expression e in a.Rhs)
                {
                    ret.AddRange(DoExpr(e));
                }
            }
            else if (s is AugmentedAssignmentStatement)
            {
                AugmentedAssignmentStatement a = s as AugmentedAssignmentStatement;
                foreach (Expression e in a.Lhs)
                {
                    ret.AddRange(DoExpr(e));
                }
                foreach (Expression e in a.Rhs)
                {
                    ret.AddRange(DoExpr(e));
                }
            }
            else if (s is BreakStatement)
            {
            }
            else if (s is CallStatement)
            {
                // Also incredibly simple...
                CallStatement c = s as CallStatement;
                return(DoExpr(c.Expression));
            }
            else if (s is DoStatement)
            {
                DoStatement d = s as DoStatement;
                return(DoChunk(d.Body));
            }
            else if (s is GenericForStatement)
            {
                GenericForStatement g = s as GenericForStatement;

                foreach (Variable v in g.VariableList)
                {
                    ret.Add(new CompletionItem(v.Name));
                }
                ret.AddRange(DoChunk(g.Body));
            }
            else if (s is NumericForStatement)
            {
                NumericForStatement n = s as NumericForStatement;
                ret.Add(new CompletionItem(n.Variable.Name));
                ret.AddRange(DoChunk(n.Body));
            }
            else if (s is FunctionStatement)
            {
                FunctionStatement f = s as FunctionStatement;
                ret.AddRange(DoExpr(f.Name));
                foreach (Variable v in f.Arguments)
                {
                    ret.Add(new CompletionItem(v.Name));
                }
                ret.AddRange(DoChunk(f.Body));
            }
            else if (s is GotoStatement)
            {
            }
            else if (s is IfStmt)
            {
                IfStmt i = s as IfStmt;
                for (int x = 0; x < i.Clauses.Count; x++)
                {
                    ret.AddRange(DoStatement(i.Clauses[x]));
                }
            }
            else if (s is LabelStatement)
            {
            }
            else if (s is RepeatStatement)
            {
                RepeatStatement r = s as RepeatStatement;
                ret.AddRange(DoChunk(r.Body));
                ret.AddRange(DoExpr(r.Condition));
            }
            else if (s is ReturnStatement)
            {
                // no variable defined here. hopefully.
            }
            else if (s is UsingStatement)
            {
                UsingStatement u = s as UsingStatement;
                ret.AddRange(DoStatement(u.Vars));
                ret.AddRange(DoChunk(u.Body));
            }
            else if (s is WhileStatement)
            {
                WhileStatement w = s as WhileStatement;
                ret.AddRange(DoExpr(w.Condition));
                ret.AddRange(DoChunk(w.Body));
            }

            else if (s is ElseIfStmt)
            {
                ElseIfStmt e = s as ElseIfStmt;
                return(DoChunk(e.Body));
            }
            else if (s is ElseStmt)
            {
                return(DoChunk(((ElseStmt)s).Body));
            }

            return(ret);
        }
Пример #11
0
 public virtual void VisitRepeatStatement(RepeatStatement repeatStatement)
 {
     DefaultVisit(repeatStatement);
 }
Пример #12
0
        internal string DoStatement(Statement s, ref int i)
        {
            // If the statement contains a body, we cant just fromTokens it, as it's body might not be
            // fully tokenized input. Therefore, we run DoChunk on Body's

            if (s.ScannedTokens != null && s.ScannedTokens.Count > 0)
            {
                if (s is AssignmentStatement && !(s is AugmentedAssignmentStatement))
                {
                    AssignmentStatement a  = s as AssignmentStatement;
                    StringBuilder       sb = new StringBuilder();
                    if (a.IsLocal)
                    {
                        sb.Append(fromToken(a.ScannedTokens[i++], a.Scope));
                        sb.Append(" ");
                    }
                    for (int i2 = 0; i2 < a.Lhs.Count; i2++)
                    {
                        sb.Append(DoExpr(a.Lhs[i2], s.ScannedTokens, ref i, s.Scope));
                        if (i2 != a.Lhs.Count - 1)
                        {
                            sb.Append(fromToken(a.ScannedTokens[i++], a.Scope));
                            sb.Append(" ");
                        }
                    }
                    if (a.Rhs.Count > 0)
                    {
                        sb.Append(" ");
                        sb.Append(fromToken(a.ScannedTokens[i++], a.Scope));
                        sb.Append(" ");
                        for (int i2 = 0; i2 < a.Rhs.Count; i2++)
                        {
                            sb.Append(DoExpr(a.Rhs[i2], s.ScannedTokens, ref i, s.Scope));
                            if (i2 != a.Rhs.Count - 1)
                            {
                                sb.Append(fromToken(a.ScannedTokens[i++], s.Scope));
                                sb.Append(" ");
                            }
                        }
                    }

                    return(sb.ToString());
                }
                else if (s is AugmentedAssignmentStatement)
                {
                    AugmentedAssignmentStatement a = s as AugmentedAssignmentStatement;
                    StringBuilder sb = new StringBuilder();
                    //sb.Append(DoExpr(a.Lhs[0]));
                    if (a.IsLocal)
                    {
                        sb.Append(fromToken(a.ScannedTokens[i++], a.Scope));
                        sb.Append(" ");
                    }
                    Expression assignment = ((BinOpExpr)a.Rhs[0]).Rhs;
                    Expression tmp        = ((BinOpExpr)a.Rhs[0]).Lhs;
                    sb.Append(DoExpr(tmp, s.ScannedTokens, ref i, s.Scope));
                    sb.Append(" ");
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                    sb.Append(" ");
                    sb.Append(DoExpr(assignment, s.ScannedTokens, ref i, s.Scope));
                    return(sb.ToString());
                }
                else if (s is BreakStatement)
                {
                    // HAHAHA this is incredibly simple...
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is ContinueStatement)
                {
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is CallStatement)
                {
                    // Also incredibly simple...
                    return(DoExpr(((CallStatement)s).Expression, s.ScannedTokens, ref i, s.Scope));
                }
                else if (s is DoStatement)
                {
                    DoStatement   d  = s as DoStatement;
                    StringBuilder sb = new StringBuilder();
                    sb.Append(fromToken(d.ScannedTokens[0], s.Scope)); // 'do'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(d.Body, ref i));
                    sb.Append(nldedent());
                    sb.Append(fromToken(d.ScannedTokens[d.ScannedTokens.Count - 1], s.Scope)); // end
                    return(sb.ToString());
                }
                else if (s is GenericForStatement)
                {
                    GenericForStatement g  = s as GenericForStatement;
                    StringBuilder       sb = new StringBuilder();
                    sb.Append(fromToken(g.ScannedTokens[i++], s.Scope)); // 'for'
                    sb.Append(" ");
                    for (int x = 0; x < g.VariableList.Count; x++)
                    {
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                        if (x != g.VariableList.Count - 1)
                        {
                            sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // ','
                            sb.Append(" ");
                        }
                    }
                    sb.Append(" ");
                    sb.Append(fromToken(g.ScannedTokens[i++], s.Scope)); // 'in'
                    sb.Append(" ");
                    for (int x = 0; x < g.Generators.Count; x++)
                    {
                        //sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                        DoExpr(g.Generators[x], g.ScannedTokens, ref i, s.Scope);
                        if (x != g.VariableList.Count - 1)
                        {
                            sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // ','
                            sb.Append(" ");
                        }
                    }
                    sb.Append(" ");
                    sb.Append(fromToken(g.ScannedTokens[i++], s.Scope)); // 'do'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(g.Body));
                    sb.Append(nldedent());
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope)); // <end>
                    return(sb.ToString());
                }
                else if (s is NumericForStatement)
                {
                    NumericForStatement n  = s as NumericForStatement;
                    StringBuilder       sb = new StringBuilder();
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));         // 'for'
                    sb.Append(" ");
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));         // <var>
                    sb.Append(" ");
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));         // '='
                    sb.Append(" ");
                    sb.Append(DoExpr(n.Start, n.ScannedTokens, ref i, s.Scope)); // <start>
                    //sb.Append(" ");
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));         // ','
                    sb.Append(" ");
                    sb.Append(DoExpr(n.End, n.ScannedTokens, ref i, s.Scope));   // <end>
                    if (n.Step != null)
                    {
                        sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));        // ','
                        sb.Append(" ");
                        sb.Append(DoExpr(n.Step, n.ScannedTokens, ref i, s.Scope)); // <step>
                        sb.Append(" ");
                    }
                    else
                    {
                        sb.Append(" ");
                    }
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope)); // 'do'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(n.Body));
                    sb.Append(nldedent());
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope)); // <end>
                    return(sb.ToString());
                }
                else if (s is FunctionStatement)
                {
                    FunctionStatement f  = s as FunctionStatement;
                    StringBuilder     sb = new StringBuilder();

                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'function'
                    sb.Append(" ");
                    sb.Append(DoExpr(f.Name, s.ScannedTokens, ref i, s.Scope));
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // '('
                    for (int i2 = 0; i2 < f.Arguments.Count; i2++)
                    {
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                        if (i2 != f.Arguments.Count - 1)// || f.IsVararg)
                        {
                            sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                            sb.Append(" ");
                        }
                    }
                    if (f.IsVararg)
                    {
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                        sb.Append(" ");
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // ')'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(f.Body));
                    indent--;
                    sb.Append(options.EOL);
                    sb.Append(writeIndent());
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope)); // <end>

                    sb.Append(options.EOL);

                    return(sb.ToString());
                }
                else if (s is GotoStatement)
                {
                    // goto <string label>, so no expr
                    //GotoStatement g = s as GotoStatement;
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is IfStmt)
                {
                    IfStmt        ifs = s as IfStmt;
                    StringBuilder sb  = new StringBuilder();

                    foreach (SubIfStmt clause in ifs.Clauses)
                    {
                        int i3 = 0;
                        if (clause is ElseIfStmt)
                        {
                            ElseIfStmt c = clause as ElseIfStmt;

                            sb.Append(fromToken(c.ScannedTokens[i3++], s.Scope)); // if/elseif
                            sb.Append(" ");
                            sb.Append(DoExpr(c.Condition, c.ScannedTokens, ref i3, c.Scope));
                            sb.Append(" ");
                            sb.Append(fromToken(c.ScannedTokens[i3++], s.Scope)); // 'then'
                            sb.Append(options.EOL);
                            indent++;
                            sb.Append(DoChunk(clause.Body));
                            sb.Append(nldedent());
                        }
                        else if (clause is ElseStmt)
                        {
                            sb.Append(fromToken(clause.ScannedTokens[i3++], s.Scope)); // if/elseif
                            sb.Append(options.EOL);
                            indent++;
                            sb.Append(DoChunk(clause.Body));
                            sb.Append(nldedent());
                        }
                        else
                        {
                            throw new NotImplementedException(clause.GetType().Name);
                        }
                    }
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope)); // 'end'
                    return(sb.ToString());
                }
                else if (s is LabelStatement)
                {
                    // ::<string label>::, so no expr
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is RepeatStatement)
                {
                    RepeatStatement r  = s as RepeatStatement;
                    StringBuilder   sb = new StringBuilder();
                    sb.Append(fromToken(r.ScannedTokens[0], s.Scope));
                    i = 1;
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(r.Body, ref i));
                    sb.Append(nldedent());
                    sb.Append(fromToken(r.ScannedTokens[i++], r.Scope));
                    sb.Append(" ");
                    sb.Append(DoExpr(r.Condition, r.ScannedTokens, ref i, r.Scope));
                    return(sb.ToString());
                }
                else if (s is ReturnStatement)
                {
                    ReturnStatement rs = s as ReturnStatement;
                    StringBuilder   sb = new StringBuilder();
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'return'
                    sb.Append(" ");
                    for (int x = 0; x < rs.Arguments.Count; x++)
                    {
                        sb.Append(DoExpr(rs.Arguments[x], rs.ScannedTokens, ref i, s.Scope));
                        if (x != rs.Arguments.Count - 1)
                        {
                            sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // ','
                            sb.Append(" ");
                        }
                    }
                    return(sb.ToString());
                }
                else if (s is UsingStatement)
                {
                    UsingStatement u  = s as UsingStatement;
                    StringBuilder  sb = new StringBuilder();
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'using'
                    sb.Append(" ");

                    AssignmentStatement a = u.Vars;
                    for (int i2 = 0; i2 < a.Lhs.Count; i2++)
                    {
                        sb.Append(DoExpr(a.Lhs[i2], u.ScannedTokens, ref i, s.Scope));
                        if (i2 != a.Lhs.Count - 1)
                        {
                            sb.Append(fromToken(u.ScannedTokens[i++], a.Scope));
                            sb.Append(" ");
                        }
                    }
                    if (a.Rhs.Count > 0)
                    {
                        sb.Append(" ");
                        sb.Append(fromToken(u.ScannedTokens[i++], a.Scope)); // '='
                        sb.Append(" ");
                        for (int i2 = 0; i2 < a.Rhs.Count; i2++)
                        {
                            sb.Append(DoExpr(a.Rhs[i2], u.ScannedTokens, ref i, s.Scope));
                            if (i2 != a.Rhs.Count - 1)
                            {
                                sb.Append(fromToken(u.ScannedTokens[i++], s.Scope));
                                sb.Append(" ");
                            }
                        }
                    }
                    sb.Append(" ");
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'do'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(u.Body));
                    sb.Append(nldedent());
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope)); // 'end'
                    return(sb.ToString());
                }
                else if (s is WhileStatement)
                {
                    WhileStatement w  = s as WhileStatement;
                    StringBuilder  sb = new StringBuilder();
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'while'
                    sb.Append(" ");
                    sb.Append(DoExpr(w.Condition, w.ScannedTokens, ref i, s.Scope));
                    sb.Append(" ");
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope)); // 'do'
                    sb.Append(options.EOL);
                    indent++;
                    sb.Append(DoChunk(w.Body));
                    sb.Append(nldedent());
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }
            }
            else // No token stream, beautify
            {
                return(beautifier.DoStatement(s));
            }

            throw new NotImplementedException(s.GetType().Name + " is not implemented");
        }
Пример #13
0
        Statement ParseStatement(Scope scope)
        {
            int       startP    = reader.p;
            int       startLine = reader.Peek().Line;
            Statement stat      = null;

            // print(tok.Peek().Print())
            if (reader.ConsumeKeyword("if"))
            {
                //setup
                IfStmt _if = new IfStmt();

                //clauses
                do
                {
                    int        sP       = reader.p;
                    Expression nodeCond = ParseExpr(scope);

                    if (!reader.ConsumeKeyword("then"))
                    {
                        error("'then' expected");
                    }

                    List <Statement> nodeBody = ParseStatementList(scope);

                    List <Token> range = new List <Token>();
                    range.Add(reader.tokens[sP - 1]);
                    range.AddRange(reader.Range(sP, reader.p));

                    _if.Clauses.Add(new ElseIfStmt(scope)
                    {
                        Condition     = nodeCond,
                        Body          = nodeBody,
                        ScannedTokens = range
                    });
                }while (reader.ConsumeKeyword("elseif"));

                // else clause
                if (reader.ConsumeKeyword("else"))
                {
                    int sP = reader.p;
                    List <Statement> nodeBody = ParseStatementList(scope);
                    List <Token>     range    = new List <Token>();
                    range.Add(reader.tokens[sP - 1]);
                    range.AddRange(reader.Range(sP, reader.p));

                    _if.Clauses.Add(new ElseStmt(scope)
                    {
                        Body          = nodeBody,
                        ScannedTokens = range
                    });
                }

                // end
                if (!reader.ConsumeKeyword("end"))
                {
                    error("'end' expected");
                }

                stat = _if;
            }
            else if (reader.ConsumeKeyword("while"))
            {
                WhileStatement w = new WhileStatement(scope);

                // condition
                Expression nodeCond = ParseExpr(scope);

                // do
                if (!reader.ConsumeKeyword("do"))
                {
                    error("'do' expected");
                }

                // body
                List <Statement> body = ParseStatementList(scope);

                //end
                if (!reader.ConsumeKeyword("end"))
                {
                    error("'end' expected");
                }


                // return
                w.Condition = nodeCond;
                w.Body      = body;
                stat        = w;
            }
            else if (reader.ConsumeKeyword("do"))
            {
                // do block
                List <Statement> b = ParseStatementList(scope);

                if (!reader.ConsumeKeyword("end"))
                {
                    error("'end' expected");
                }

                stat = new DoStatement(scope)
                {
                    Body = b
                };
            }
            else if (reader.ConsumeKeyword("for"))
            {
                //for block
                if (!reader.Is(TokenType.Ident))
                {
                    error("<ident> expected");
                }

                Token baseVarName = reader.Get();
                if (reader.ConsumeSymbol('='))
                {
                    //numeric for
                    NumericForStatement forL   = new NumericForStatement(scope);
                    Variable            forVar = new Variable()
                    {
                        Name = baseVarName.Data
                    };
                    forL.Scope.AddLocal(forVar);

                    Expression startEx = ParseExpr(scope);

                    if (!reader.ConsumeSymbol(','))
                    {
                        error("',' expected");
                    }

                    Expression endEx = ParseExpr(scope);

                    Expression stepEx = null;
                    if (reader.ConsumeSymbol(','))
                    {
                        stepEx = ParseExpr(scope);
                    }
                    if (!reader.ConsumeKeyword("do"))
                    {
                        error("'do' expected");
                    }


                    List <Statement> body = ParseStatementList(forL.Scope);

                    if (!reader.ConsumeKeyword("end"))
                    {
                        error("'end' expected");
                    }


                    forL.Variable = forVar;
                    forL.Start    = startEx;
                    forL.End      = endEx;
                    forL.Step     = stepEx;
                    forL.Body     = body;
                    stat          = forL;
                }
                else
                {
                    // generic for
                    GenericForStatement forL = new GenericForStatement(scope);

                    List <Variable> varList = new List <Variable> {
                        forL.Scope.CreateLocal(baseVarName.Data)
                    };
                    while (reader.ConsumeSymbol(','))
                    {
                        if (!reader.Is(TokenType.Ident))
                        {
                            error("for variable expected");
                        }

                        varList.Add(forL.Scope.CreateLocal(reader.Get().Data));
                    }
                    if (!reader.ConsumeKeyword("in"))
                    {
                        error("'in' expected");
                    }

                    List <Expression> generators = new List <Expression>();
                    Expression        first      = ParseExpr(scope);

                    generators.Add(first);
                    while (reader.ConsumeSymbol(','))
                    {
                        Expression gen = ParseExpr(scope);
                        generators.Add(gen);
                    }
                    if (!reader.ConsumeKeyword("do"))
                    {
                        error("'do' expected");
                    }

                    List <Statement> body = ParseStatementList(forL.Scope);

                    if (!reader.ConsumeKeyword("end"))
                    {
                        error("'end' expected");
                    }

                    forL.VariableList = varList;
                    forL.Generators   = generators;
                    forL.Body         = body;
                    stat = forL;
                }
            }
            else if (reader.ConsumeKeyword("repeat"))
            {
                List <Statement> body = ParseStatementList(scope);

                if (!reader.ConsumeKeyword("until"))
                {
                    error("'until' expected");
                }

                Expression cond = ParseExpr(scope);

                RepeatStatement r = new RepeatStatement(scope);
                r.Condition = cond;
                r.Body      = body;
                stat        = r;
            }
            else if (reader.ConsumeKeyword("function"))
            {
                if (!reader.Is(TokenType.Ident))
                {
                    error("function name expected");
                }

                Expression name = ParseSuffixedExpr(scope, true);
                // true: only dots and colons

                FunctionStatement func = ParseFunctionArgsAndBody(scope);

                func.IsLocal = false;
                func.Name    = name;
                stat         = func;
            }
            else if (reader.ConsumeKeyword("local"))
            {
                if (reader.Is(TokenType.Ident))
                {
                    List <string> varList = new List <string> {
                        reader.Get().Data
                    };
                    while (reader.ConsumeSymbol(','))
                    {
                        if (!reader.Is(TokenType.Ident))
                        {
                            error("local variable name expected");
                        }
                        varList.Add(reader.Get().Data);
                    }

                    List <Expression> initList = new List <Expression>();
                    if (reader.ConsumeSymbol('='))
                    {
                        do
                        {
                            Expression ex = ParseExpr(scope);
                            initList.Add(ex);
                        } while (reader.ConsumeSymbol(','));
                    }

                    //now patch var list
                    //we can't do this before getting the init list, because the init list does not
                    //have the locals themselves in scope.
                    List <Expression> newVarList = new List <Expression>();
                    for (int i = 0; i < varList.Count; i++)
                    {
                        Variable x = scope.CreateLocal(varList[i]);
                        newVarList.Add(new VariableExpression {
                            Var = x
                        });
                    }

                    AssignmentStatement l = new AssignmentStatement();
                    l.Lhs     = newVarList;
                    l.Rhs     = initList;
                    l.IsLocal = true;
                    stat      = l;
                }
                else if (reader.ConsumeKeyword("function"))
                {
                    if (!reader.Is(TokenType.Ident))
                    {
                        error("Function name expected");
                    }
                    string   name     = reader.Get().Data;
                    Variable localVar = scope.CreateLocal(name);

                    FunctionStatement func = ParseFunctionArgsAndBody(scope);

                    func.Name = new VariableExpression {
                        Var = localVar
                    };
                    func.IsLocal = true;
                    stat         = func;
                }
                else
                {
                    error("local variable or function definition expected");
                }
            }
#if !VANILLA_LUA
            else if (reader.ConsumeSymbol("::"))
            {
                if (!reader.Is(TokenType.Ident))
                {
                    error("label name expected");
                }

                string label = reader.Get().Data;
                if (!reader.ConsumeSymbol("::"))
                {
                    error("'::' expected");
                }

                LabelStatement l = new LabelStatement();
                l.Label = label;
                stat    = l;
            }
#endif
            else if (reader.ConsumeKeyword("return"))
            {
                List <Expression> exprList = new List <Expression>();
                if (!reader.IsKeyword("end") && !reader.IsEof())
                {
                    Expression firstEx = ParseExpr(scope);
                    exprList.Add(firstEx);
                    while (reader.ConsumeSymbol(','))
                    {
                        Expression ex = ParseExpr(scope);
                        exprList.Add(ex);
                    }
                }
                ReturnStatement r = new ReturnStatement();
                r.Arguments = exprList;
                stat        = r;
            }
            else if (reader.ConsumeKeyword("break"))
            {
                stat = new BreakStatement();
            }
            else if (reader.ConsumeKeyword("continue"))
            {
                stat = new ContinueStatement();
            }
#if !VANILLA_LUA
            else if (reader.ConsumeKeyword("goto"))
            {
                if (!reader.Is(TokenType.Ident))
                {
                    error("label expected");
                }

                string        label = reader.Get().Data;
                GotoStatement g     = new GotoStatement();
                g.Label = label;
                stat    = g;
            }
            else if (reader.ConsumeKeyword("using"))
            {
                // using <a, b = 1, x()> do <statements> end
                UsingStatement us = new UsingStatement(scope);
                us.Scope = new Scope(scope);

                List <Expression> lhs = new List <Expression> {
                    ParseExpr(us.Scope)
                };
                while (reader.ConsumeSymbol(','))
                {
                    lhs.Add(ParseSuffixedExpr(us.Scope, true));
                }

                // equals
                if (!reader.ConsumeSymbol('='))
                {
                    error("'=' expected");
                }

                //rhs
                List <Expression> rhs = new List <Expression>();
                rhs.Add(ParseExpr(us.Scope));
                while (reader.ConsumeSymbol(','))
                {
                    rhs.Add(ParseExpr(scope));
                }

                AssignmentStatement a = new AssignmentStatement();
                a.Lhs     = lhs;
                a.Rhs     = rhs;
                a.IsLocal = true;

                if (!reader.ConsumeKeyword("do"))
                {
                    error("'do' expected");
                }

                List <Statement> block = ParseStatementList(us.Scope);

                if (!reader.ConsumeKeyword("end"))
                {
                    error("'end' expected");
                }

                us.Vars = a;
                us.Body = block;
                stat    = us;
            }
#endif
            else
            {
                // statementParseExpr
                Expression suffixed = ParseSuffixedExpr(scope);
                // assignment or call?
                if (reader.IsSymbol(',') || reader.IsSymbol('='))
                {
                    // check that it was not parenthesized, making it not an lvalue
                    if (suffixed.ParenCount > 0)
                    {
                        error("Can not assign to parenthesized expression, it is not an lvalue");
                    }

                    // more processing needed
                    List <Expression> lhs = new List <Expression> {
                        suffixed
                    };
                    while (reader.ConsumeSymbol(','))
                    {
                        lhs.Add(ParseSuffixedExpr(scope));
                    }

                    // equals
                    if (!reader.ConsumeSymbol('='))
                    {
                        error("'=' expected");
                    }

                    //rhs
                    List <Expression> rhs = new List <Expression>();
                    rhs.Add(ParseExpr(scope));
                    while (reader.ConsumeSymbol(','))
                    {
                        rhs.Add(ParseExpr(scope));
                    }

                    AssignmentStatement a = new AssignmentStatement();
                    a.Lhs = lhs;
                    a.Rhs = rhs;
                    stat  = a;
                }
#if !VANILLA_LUA
                else if (isAugmentedAssignment(reader.Peek()))
                {
                    AugmentedAssignmentStatement aas = new AugmentedAssignmentStatement();
                    Expression left        = suffixed;
                    Expression right       = null;
                    string     augmentedOp = reader.Get().Data;
                    right = ParseExpr(scope);
                    BinOpExpr nRight = new BinOpExpr();
                    nRight.Lhs = left;
                    nRight.Op  = augmentedOp.Substring(0, augmentedOp.Length - 1); // strip the '='
                    nRight.Rhs = right;

                    aas.Lhs = new List <Expression> {
                        left
                    };
                    aas.Rhs = new List <Expression> {
                        nRight
                    };
                    stat = aas;
                }
#endif
                else if (suffixed is CallExpr ||
                         suffixed is TableCallExpr ||
                         suffixed is StringCallExpr)
                {
                    //it's a call statement
                    CallStatement c = new CallStatement();
                    c.Expression = suffixed;
                    stat         = c;
                }
                else
                {
                    error("assignment statement expected");
                }
            }

            stat.ScannedTokens = reader.Range(startP, reader.p);
            if (reader.Peek().Data == ";" && reader.Peek().Type == TokenType.Symbol)
            {
                stat.HasSemicolon   = true;
                stat.SemicolonToken = reader.Get();
            }
            if (stat.Scope == null)
            {
                stat.Scope = scope;
            }
            stat.LineNumber = startLine;
            return(stat);
        }
Пример #14
0
 public virtual void VisitRepeatStatement(RepeatStatement node) => DefaultVisit(node);
Пример #15
0
 public abstract void ConstructRepeatStatement(RepeatStatement node);
Пример #16
0
 protected virtual ASTNode FoldRepeatStatement(RepeatStatement node, params Object[] args)
 {
     node.SetBody(this.FoldStatementList(node.Body));
     node.SetCondition(this.Fold(node.Condition));
     return(node);
 }
Пример #17
0
        internal string DoStatement(Statement s)
        {
            // If the statement contains a body, we cant just fromTokens it, as it's body might not be
            // fully tokenized input. Therefore, we run DoChunk on Body's

            if (s.ScannedTokens != null && s.ScannedTokens.Count > 0)
            {
                if (s is AssignmentStatement && !(s is AugmentedAssignmentStatement))
                {
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is AugmentedAssignmentStatement)
                {
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is BreakStatement)
                {
                    // HAHAHA this is incredibly simple...
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is CallStatement)
                {
                    // Also incredibly simple...
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is DoStatement)
                {
                    DoStatement   d  = s as DoStatement;
                    StringBuilder sb = new StringBuilder();
                    sb.Append(fromToken(d.ScannedTokens[0], s.Scope)); // 'do'
                    sb.Append(DoChunk(d.Body));
                    sb.Append(fromToken(d.ScannedTokens[d.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }
                else if (s is GenericForStatement)
                {
                    GenericForStatement g  = s as GenericForStatement;
                    StringBuilder       sb = new StringBuilder();
                    int i = 0;
                    while (g.ScannedTokens[i].Data != "do")
                    {
                        sb.Append(fromToken(g.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(g.ScannedTokens[i++], s.Scope));
                    sb.Append(DoChunk(g.Body));
                    sb.Append(fromToken(g.ScannedTokens[g.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }
                else if (s is NumericForStatement)
                {
                    NumericForStatement n  = s as NumericForStatement;
                    StringBuilder       sb = new StringBuilder();
                    int i = 0;
                    while (n.ScannedTokens[i].Data != "do")
                    {
                        sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(n.ScannedTokens[i++], s.Scope));
                    sb.Append(DoChunk(n.Body));
                    sb.Append(fromToken(n.ScannedTokens[n.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }
                else if (s is FunctionStatement)
                {
                    FunctionStatement f  = s as FunctionStatement;
                    StringBuilder     sb = new StringBuilder();

                    int i = 0;
                    while (f.ScannedTokens[i].Data != ")")
                    {
                        sb.Append(fromToken(f.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(f.ScannedTokens[i++], s.Scope));

                    sb.Append(DoChunk(f.Body));
                    sb.Append(fromToken(f.ScannedTokens[f.ScannedTokens.Count - 1], s.Scope));

                    return(sb.ToString());
                }
                else if (s is GotoStatement)
                {
                    GotoStatement g = s as GotoStatement;
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is IfStmt)
                {
                    IfStmt        i  = s as IfStmt;
                    StringBuilder sb = new StringBuilder();

                    foreach (SubIfStmt clause in i.Clauses)
                    {
                        int i2 = 0;
                        while (clause.ScannedTokens[i2].Data != "then")
                        {
                            sb.Append(fromToken(clause.ScannedTokens[i2++], clause.Scope));
                        }
                        sb.Append(DoChunk(clause.Body));
                        sb.Append(fromToken(clause.ScannedTokens[i2++], clause.Scope));
                    }
                    return(sb.ToString());
                }
                else if (s is LabelStatement)
                {
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is RepeatStatement)
                {
                    RepeatStatement r  = s as RepeatStatement;
                    StringBuilder   sb = new StringBuilder();
                    sb.Append(fromToken(r.ScannedTokens[0], s.Scope));
                    sb.Append(DoChunk(r.Body));
                    int i = 0;
                    for (int i2 = 0; i2 < r.ScannedTokens.Count; i2++)
                    {
                        if (r.ScannedTokens[i2].Data == "until")
                        {
                            i = i2;
                        }
                    }

                    for (int i2 = i; i2 < r.ScannedTokens.Count; i2++)
                    {
                        sb.Append(fromToken(r.ScannedTokens[i2], s.Scope));
                    }
                    return(sb.ToString());
                }
                else if (s is ReturnStatement)
                {
                    return(fromTokens(s.ScannedTokens, s.Scope));
                }
                else if (s is UsingStatement)
                {
                    UsingStatement u  = s as UsingStatement;
                    StringBuilder  sb = new StringBuilder();
                    int            i  = 0;
                    while (s.ScannedTokens[i].Data != "do")
                    {
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));

                    sb.Append(DoChunk(u.Body));
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }
                else if (s is WhileStatement)
                {
                    WhileStatement w  = s as WhileStatement;
                    StringBuilder  sb = new StringBuilder();
                    int            i  = 0;
                    while (s.ScannedTokens[i].Data != "do")
                    {
                        sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));
                    }
                    sb.Append(fromToken(s.ScannedTokens[i++], s.Scope));

                    sb.Append(DoChunk(w.Body));
                    sb.Append(fromToken(s.ScannedTokens[s.ScannedTokens.Count - 1], s.Scope));
                    return(sb.ToString());
                }

                /*
                 * else if (s is ElseIfStmt)
                 * {
                 *  ElseIfStmt e = s as ElseIfStmt;
                 *  string s2 = DoExpr(e.Condition) + " then" + EOL;
                 *  s2 += DoChunk(e.Body);
                 *  return s2;
                 * }
                 * else if (s is ElseStmt)
                 * {
                 *  return DoChunk(((ElseStmt)s).Body);
                 * }
                 */
            }
            else // No token stream, beautify
            {
                return(beautifier.DoStatement(s));
            }

            throw new NotImplementedException(s.GetType().Name + " is not implemented");
        }
Пример #18
0
        internal string DoStatement(Statement s)
        {
            if (s is AssignmentStatement && !(s is AugmentedAssignmentStatement))
            {
                AssignmentStatement a  = s as AssignmentStatement;
                StringBuilder       sb = new StringBuilder();
                if (a.IsLocal)
                {
                    sb.Append("local ");
                }
                for (int i = 0; i < a.Lhs.Count; i++)
                {
                    sb.Append(DoExpr(a.Lhs[i]));
                    if (i != a.Lhs.Count - 1)
                    {
                        sb.Append(",");
                    }
                }
                if (a.Rhs.Count > 0)
                {
                    sb.Append("=");
                    for (int i = 0; i < a.Rhs.Count; i++)
                    {
                        sb.Append(DoExpr(a.Rhs[i]));
                        if (i != a.Rhs.Count - 1)
                        {
                            sb.Append(",");
                        }
                    }
                }
                return(sb.ToString());
            }
            else if (s is AugmentedAssignmentStatement)
            {
                AugmentedAssignmentStatement a = s as AugmentedAssignmentStatement;
                StringBuilder sb = new StringBuilder();
                //sb.Append(DoExpr(a.Lhs[0]));
                if (a.IsLocal)
                {
                    sb.Append("local ");
                }
                Expression assignment = ((BinOpExpr)a.Rhs[0]).Rhs;
                sb.Append(DoExpr((((BinOpExpr)a.Rhs[0]).Lhs)));
                sb.Append("" + ((BinOpExpr)a.Rhs[0]).Op + "=");
                sb.Append(DoExpr(assignment));
                return(sb.ToString());
            }
            else if (s is BreakStatement)
            {
                // HAHAHA this is incredibly simple...
                return("break");
            }
            else if (s is CallStatement)
            {
                // Also incredibly simple...
                CallStatement c = s as CallStatement;
                return(DoExpr(c.Expression));
            }
            else if (s is DoStatement)
            {
                DoStatement   d  = s as DoStatement;
                StringBuilder sb = new StringBuilder();
                sb.Append("do ");
                sb.Append(DoChunk(d.Body));
                sb.Append(" end");
                return(sb.ToString());
            }
            else if (s is GenericForStatement)
            {
                GenericForStatement g  = s as GenericForStatement;
                StringBuilder       sb = new StringBuilder();
                sb.Append("for ");
                for (int i = 0; i < g.VariableList.Count; i++)
                {
                    sb.Append(g.VariableList[i].Name);
                    if (i != g.VariableList.Count - 1)
                    {
                        sb.Append(",");
                    }
                }
                sb.Append(" in ");
                for (int i = 0; i < g.Generators.Count; i++)
                {
                    sb.Append(DoExpr(g.Generators[i]));
                    if (i != g.Generators.Count - 1)
                    {
                        sb.Append(",");
                    }
                }
                sb.Append(" do ");
                sb.Append(DoChunk(g.Body));
                sb.Append(" end");
                return(sb.ToString());
            }
            else if (s is NumericForStatement)
            {
                NumericForStatement n  = s as NumericForStatement;
                StringBuilder       sb = new StringBuilder();
                sb.Append("for ");
                sb.Append(n.Variable.Name);
                sb.Append("=");
                sb.Append(DoExpr(n.Start));
                sb.Append(",");
                sb.Append(DoExpr(n.End));
                if (n.Step != null)
                {
                    sb.Append(",");
                    sb.Append(DoExpr(n.Step));
                }
                sb.Append(" do ");
                sb.Append(DoChunk(n.Body));
                sb.Append(" end");
                return(sb.ToString());
            }
            else if (s is FunctionStatement)
            {
                FunctionStatement f  = s as FunctionStatement;
                StringBuilder     sb = new StringBuilder();
                sb.Append("function " + DoExpr(f.Name) + "(");
                for (int i = 0; i < f.Arguments.Count; i++)
                {
                    sb.Append(f.Arguments[i].Name);
                    if (i != f.Arguments.Count - 1 || f.IsVararg)
                    {
                        sb.Append(",");
                    }
                }
                if (f.IsVararg)
                {
                    sb.Append("...");
                }
                sb.Append(")");
                sb.Append(" " + DoStatement(f.Body[0]));
                sb.Append(" end");

                return(sb.ToString());
            }
            else if (s is GotoStatement)
            {
                GotoStatement g = s as GotoStatement;
                return("goto " + g.Label);
            }
            else if (s is IfStmt)
            {
                IfStmt        i  = s as IfStmt;
                StringBuilder sb = new StringBuilder();
                for (int x = 0; x < i.Clauses.Count; x++)
                {
                    string ss = DoStatement(i.Clauses[x]);
                    if (x == 0)
                    {
                        sb.Append("if ");
                        sb.Append(ss);
                    }
                    else if (i.Clauses[x] is ElseStmt)
                    {
                        sb.Append(" else ");
                        sb.Append(ss);
                    }
                    else
                    {
                        sb.Append("elseif " + ss);
                    }
                }
                sb.Append(" end");
                return(sb.ToString());
            }
            else if (s is LabelStatement)
            {
                LabelStatement l = s as LabelStatement;
                return("::" + l.Label + "::");
            }
            else if (s is RepeatStatement)
            {
                RepeatStatement r  = s as RepeatStatement;
                StringBuilder   sb = new StringBuilder();
                sb.Append("repeat ");
                sb.Append(DoChunk(r.Body));
                sb.Append(" until " + DoExpr(r.Condition));
                return(sb.ToString());
            }
            else if (s is ReturnStatement)
            {
                ReturnStatement r  = s as ReturnStatement;
                StringBuilder   sb = new StringBuilder();
                sb.Append("return ");
                for (int i = 0; i < r.Arguments.Count; i++)
                {
                    sb.Append(DoExpr(r.Arguments[i]));
                    if (i != r.Arguments.Count - 1)
                    {
                        sb.Append(",");
                    }
                }
                return(sb.ToString());
            }
            else if (s is UsingStatement)
            {
                UsingStatement u  = s as UsingStatement;
                StringBuilder  sb = new StringBuilder();
                sb.Append("using ");
                sb.Append(DoStatement(u.Vars));
                sb.Append(" do ");
                sb.Append(DoChunk(u.Body));
                sb.Append(" end");
                return(sb.ToString());
            }
            else if (s is WhileStatement)
            {
                WhileStatement w  = s as WhileStatement;
                StringBuilder  sb = new StringBuilder();
                sb.Append("while ");
                sb.Append(DoExpr(w.Condition));
                sb.Append(" do ");
                sb.Append(DoChunk(w.Body));
                sb.Append(" end");
                return(sb.ToString());
            }

            else if (s is ElseIfStmt)
            {
                ElseIfStmt e  = s as ElseIfStmt;
                string     s2 = DoExpr(e.Condition) + " then ";
                s2 += DoChunk(e.Body);
                return(s2);
            }
            else if (s is ElseStmt)
            {
                return(DoChunk(((ElseStmt)s).Body));
            }

            throw new NotImplementedException(s.GetType().Name + " is not implemented");
        }