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

net.hasor.dataql.domain.SwitchInst Maven / Gradle / Ivy

There is a newer version: 4.2.5
Show newest version
/*
 * Copyright 2008-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.hasor.dataql.domain;
import net.hasor.dataql.domain.compiler.CompilerStack;
import net.hasor.dataql.domain.compiler.InstQueue;
import net.hasor.dataql.domain.compiler.Label;

import java.util.ArrayList;
import java.util.List;
/**
 * if指令
 * @author 赵永春([email protected])
 * @version : 2017-03-23
 */
public class SwitchInst extends Inst {
    public static class SwitchExpression {
        private Expression testExpression;
        private BlockSet   instBlockSet;
    }
    private List testBlockSet;
    private BlockSet               elseBlockSet;
    public SwitchInst() {
        this.testBlockSet = new ArrayList();
    }
    //
    /** 添加条件分支 */
    public void addBlockSet(Expression testExp, BlockSet instBlockSet) {
        SwitchExpression se = new SwitchExpression();
        se.testExpression = testExp;
        se.instBlockSet = instBlockSet;
        this.testBlockSet.add(se);
    }
    /** 设置默认条件分支 */
    public void setElseBlockSet(BlockSet instBlockSet) {
        this.elseBlockSet = instBlockSet;
    }
    //
    //
    @Override
    public void doCompiler(InstQueue queue, CompilerStack stackTree) {
        if (this.testBlockSet.isEmpty()) {
            queue.inst(LDC_N, 0);
            queue.inst(LDC_S, "inst if -> error.");
            queue.inst(ERR);
            return;
        }
        /*
            if (a == b)
                var a = b
            elseif (a == null)
                var b = a
            else
                var c = a
            end

            -----               // if (a == b)
            LABEL   "label_0"
            LOAD    1
            LOAD    2
            DO      "eq"
            IF      "label_1"
            ...
            GOTO    "label_4"
            -----               // elseif (a == null)
            LABEL   "label_1"
            LOAD    1
            LDC_N
            DO      "eq"
            IF      "label_2"
            ...
            GOTO    "label_4"
            -----               // else
            GOTO    "label_2"
            ...
            -----
            GOTO    "label_4"
        */
        //
        // .if 和 elseif
        //
        Label finalLabel = queue.labelDef();  // else出口 Label
        Label lastEnterIn = queue.labelDef(); // 最后一个入口 Label(随着if分支发生变化)
        //
        for (SwitchExpression switchExp : this.testBlockSet) {
            //
            // .标记if分支入口
            queue.inst(LABEL, lastEnterIn);
            //
            // .产生新的入口,流给下一个if分支使用
            lastEnterIn = queue.labelDef();
            //
            // .条件判断
            Expression testExpression = switchExp.testExpression;
            testExpression.doCompiler(queue, stackTree);
            queue.inst(IF, lastEnterIn);//如果判断失败,跳转到下一个Label
            //
            // .if的body
            BlockSet instBlockSet = switchExp.instBlockSet;
            instBlockSet.doCompiler(queue, stackTree);
            queue.inst(GOTO, finalLabel);//执行完毕,跳转到总出口
            //
        }
        // .else
        queue.inst(LABEL, lastEnterIn);
        if (this.elseBlockSet != null) {
            this.elseBlockSet.doCompiler(queue, stackTree);
            queue.inst(GOTO, finalLabel);
        }
        // .if 的结束点
        queue.inst(LABEL, finalLabel);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy