All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.libra.expr.compiler.syntax.IfParser Maven / Gradle / Ivy

/*
 * MIT License
 *
 * Copyright (c) 2018 Alibaba Group
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.libra.expr.compiler.syntax;

import com.libra.TextUtils;
import com.libra.Log;

import com.libra.expr.compiler.lex.SymbolToken;
import com.libra.expr.compiler.lex.Token;
import com.libra.expr.compiler.lex.WordToken;
import com.libra.expr.compiler.syntax.operator.Operator;
import com.libra.virtualview.common.ExprCommon;
import com.libra.virtualview.common.StringBase;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by gujicheng on 16/12/12.
 */

public class IfParser extends Parser {
    private final static String TAG = "IfParser_TMTEST";

    private final static int STATE_start = 1;
    private final static int STATE_left_bracket = 2;
    private final static int STATE_condition = 3;
    private final static int STATE_left_big_bracket = 4;
    private final static int STATE_body = 5;
    private final static int STATE_elseif = 6;

    private int mState = STATE_start;
    private SyntaxParser mSentenceParser;
    private boolean mIsElse = false;

    private int mWriteJmpPos;
    private List mJmpEndPos = new ArrayList();

    @Override
    public void reset() {
        super.reset();

        mState = STATE_start;
        mIsElse = false;
        mJmpEndPos.clear();

        if (null != mSentenceParser) {
            mSentenceParser.reset();
            mSentenceParser = null;
        }
    }

    @Override
    protected int parse(Token token) {
        int ret = RESULT_NEED_MORE;

//        Log.d(TAG, "parse token:" + token + "  state:" + mState);
        switch (mState) {
            case STATE_start:
                if (Token.TYPE_WORD == token.mType && ((WordToken) token).mValue == StringBase.STR_ID_if) {
                    mState = STATE_left_bracket;
                } else {
                    ret = RESULT_FAILED;
                }
                break;

            case STATE_left_bracket:
                if (Token.TYPE_SYMBOL == token.mType && SymbolToken.LEFT_BRACKET == ((SymbolToken) token).mValue) {
                    mState = STATE_condition;
                    mWriteJmpPos = -1;
                    if (null == mSentenceParser) {
                        mSentenceParser = new SyntaxParser();
                        mSentenceParser.setCodeGenerator(mCodeGenerator);
                        mSentenceParser.setRegisterManager(mRegisterManager);
                        mSentenceParser.setStringStore(mStringManager);
                    }
                } else {
                    ret = RESULT_FAILED;
                }
                break;

            case STATE_condition:
//                Log.d(TAG, "STATE_condition:");
                if (mSentenceParser.parse(token)) {

                } else {
//                    Log.d(TAG, "condition finished");
                    if (Token.TYPE_SYMBOL == token.mType) {
                        mSentenceParser.forceFinish();
                        if (SymbolToken.RIGHT_BRACKET == ((SymbolToken) token).mValue) {
                            Expr expr = mSentenceParser.getExpr();
                            if (null != expr) {
//                                expr.mType
                                // param ok, continue parse param
                                if (Expr.TYPE_REG == expr.mType || Expr.TYPE_VAR == expr.mType) {
                                    mCodeGenerator.writeByte(ExprCommon.OPCODE_JMP_C);
                                    // condition jump offset
                                    mWriteJmpPos = mCodeGenerator.size();
                                    mCodeGenerator.writeInt(0);

                                    // write expr
                                    Operator.writeExpr(mCodeGenerator, expr);
                                } else if (Expr.TYPE_INT == expr.mType) {
                                    if (((IntegerExpr) expr).mValue <= 0) {
                                        // jmp
                                    }
                                } else if (Expr.TYPE_FLOAT == expr.mType) {
                                    if (((FloatExpr) expr).mValue <= 0) {
                                        // jmp
                                    }
                                } else if (Expr.TYPE_STR == expr.mType) {
                                    if (TextUtils.isEmpty(this.mStringManager.getString(((StringExpr) expr).mValue))) {
                                        // jmp
                                    }
                                }
//                                Log.d(TAG, "add param continue expr:" + expr);
                                mSentenceParser.reset();

                                mState = STATE_left_big_bracket;
                            } else {
                                Log.e(TAG, "failed:" + token);
                                ret = RESULT_FAILED;
                            }
                        } else {
                            Log.e(TAG, "invalidate token1:" + token);
                            ret = RESULT_FAILED;
                        }
                    } else {
                        Log.e(TAG, "invalidate token2:" + token);
                        ret = RESULT_FAILED;
                    }
                }
                break;

            case STATE_left_big_bracket:
//                Log.d(TAG, "STATE_left_big_bracket");
                if (Token.TYPE_SYMBOL == token.mType && SymbolToken.LEFT_BIG_BRACKET == ((SymbolToken) token).mValue) {
                    mState = STATE_body;
                } else {
                    ret = RESULT_FAILED;
                }
                break;

            case STATE_body:
                if (mSentenceParser.parse(token)) {

                } else {
//                    Log.d(TAG, "STATE_body finished");
                    if (Token.TYPE_SYMBOL == token.mType) {
                        mSentenceParser.forceFinish();
                        if (SymbolToken.RIGHT_BIG_BRACKET == ((SymbolToken) token).mValue) {

                            mState = STATE_elseif;

                            mSentenceParser.reset();
                        } else {
                            Log.e(TAG, "invalidate token1:" + token);
                            ret = RESULT_FAILED;
                        }
                    } else {
                        Log.e(TAG, "invalidate token2:" + token);
                        ret = RESULT_FAILED;
                    }
                }
                break;

            case STATE_elseif:
                if ((Token.TYPE_WORD == token.mType) && ((((WordToken)token).mValue == StringBase.STR_ID_elseif) || (((WordToken)token).mValue == StringBase.STR_ID_else)) ) {
                    WordToken wt = (WordToken) token;

                    // jump to end
                    mCodeGenerator.writeByte(ExprCommon.OPCODE_JMP);
                    // jump offset
                    mJmpEndPos.add(mCodeGenerator.size());
                    mCodeGenerator.writeInt(0);

                    if (wt.mValue == StringBase.STR_ID_elseif) {
                        mState = STATE_left_bracket;
                    } else if (wt.mValue == StringBase.STR_ID_else) {
                        mState = STATE_left_big_bracket;
                        mIsElse = true;
//                        Log.d(TAG, "else coming");
                    } else {
                        ret = RESULT_FAILED;
                        Log.e(TAG, "failed");
                    }
                } else {
//                    Log.d(TAG, "if parser finished--------:" + token);
                    ret = RESULT_FINISH_BACK_1;

                    int size = mCodeGenerator.size();
                    for (int pos : mJmpEndPos) {
                        mCodeGenerator.rewriteInt(size, pos);
                    }
                }

                if (mWriteJmpPos > -1) {
                    int size = mCodeGenerator.size();
//                    Log.d(TAG, "rewrite code:" + mCodeGenerator);
//                    Log.d(TAG, "rewrite jmpc pos:" + size);
                    mCodeGenerator.rewriteInt(size, mWriteJmpPos);

                    mWriteJmpPos = -1;
                }

                break;
        }

        return ret;
    }

    @Override
    protected Expr buildExpr() {
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy