From 46fab68d4433e797db26d2aca50f330717f530a1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Jul 2010 10:42:49 +0200 Subject: [PATCH] implemented while loops --- components/compiler/controlparser.cpp | 69 +++++++++++++++++++++++++++ components/compiler/controlparser.hpp | 6 ++- components/compiler/generator.cpp | 2 +- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/components/compiler/controlparser.cpp b/components/compiler/controlparser.cpp index f34896a623..3425d2bbfb 100644 --- a/components/compiler/controlparser.cpp +++ b/components/compiler/controlparser.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "scanner.hpp" #include "generator.hpp" @@ -36,6 +37,14 @@ namespace Compiler mState = IfEndState; return true; } + else if (keyword==Scanner::K_while) + { + mExprParser.reset(); + scanner.scan (mExprParser); + + mState = WhileEndState; + return true; + } } else if (mState==IfBodyState || mState==IfElseifBodyState || mState==IfElseBodyState) { @@ -123,6 +132,61 @@ namespace Compiler return true; } } + else if (mState==WhileBodyState) + { + if (keyword==Scanner::K_endwhile) + { + Codes loop; + + Codes expr; + mExprParser.append (expr); + + Generator::jump (loop, -mCodeBlock.size()-expr.size()); + + std::copy (expr.begin(), expr.end(), std::back_inserter (mCode)); + + Codes skip; + + Generator::jumpOnZero (skip, mCodeBlock.size()+loop.size()+1); + + std::copy (skip.begin(), skip.end(), std::back_inserter (mCode)); + + std::copy (mCodeBlock.begin(), mCodeBlock.end(), std::back_inserter (mCode)); + + Codes loop2; + + Generator::jump (loop2, -mCodeBlock.size()-expr.size()-skip.size()); + + if (loop.size()!=loop2.size()) + throw std::logic_error ( + "internal compiler error: failed to generate a while loop"); + + std::copy (loop2.begin(), loop2.end(), std::back_inserter (mCode)); + + mState = WhileEndwhileState; + return true; + } + else if (keyword==Scanner::K_if || keyword==Scanner::K_while) + { + // nested + ControlParser parser (getErrorHandler(), getContext(), mLocals, mLiterals); + + if (parser.parseKeyword (keyword, loc, scanner)) + scanner.scan (parser); + + parser.appendCode (mCodeBlock); + + return true; + } + else + { + mLineParser.reset(); + if (mLineParser.parseKeyword (keyword, loc, scanner)) + scanner.scan (mLineParser); + + return true; + } + } return Parser::parseKeyword (keyword, loc, scanner); } @@ -136,13 +200,18 @@ namespace Compiler case IfEndState: mState = IfBodyState; return true; case IfElseifEndState: mState = IfElseifBodyState; return true; case IfElseEndState: mState = IfElseBodyState; return true; + + case WhileEndState: mState = WhileBodyState; return true; case IfBodyState: case IfElseifBodyState: case IfElseBodyState: + case WhileBodyState: + return true; // empty line case IfEndifState: + case WhileEndwhileState: return false; diff --git a/components/compiler/controlparser.hpp b/components/compiler/controlparser.hpp index ef244ea50e..1af9a2ca9f 100644 --- a/components/compiler/controlparser.hpp +++ b/components/compiler/controlparser.hpp @@ -21,10 +21,12 @@ namespace Compiler enum State { StartState, - IfState, IfEndState, IfBodyState, + IfEndState, IfBodyState, IfElseifEndState, IfElseifBodyState, IfElseEndState, IfElseBodyState, - IfEndifState + IfEndifState, + WhileEndState, WhileBodyState, + WhileEndwhileState }; typedef std::vector Codes; diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index d587c29824..f540f3314e 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -415,7 +415,7 @@ namespace Compiler if (offset>0) opJumpForward (code, offset); else if (offset<0) - opJumpBackward (code, offset); + opJumpBackward (code, -offset); else throw std::logic_error ("inifite loop"); }