Ruby 手写简陋编程语言 更新

crella95 · 2022年10月16日 · 最后由 crella95 回复于 2022年11月27日 · 746 次阅读

完全面向过程设计,ruby 跑的还是比 Java 慢多了

package vbs;

import java.util.ArrayList;
import java.io.*;
import java.util.Scanner;

public class Vbs {

    public static void main(String[] args) throws Exception {
        // TODO code application logic here
       Vbenv ve = new Vbenv();

       int x = (int)(2.6);
       //System.out.println(x);
//        long s = System.currentTimeMillis();
//        for(int i = 1; i < 10000000; i++){
//            x = ve.expr("3.5*4");
//        }
//        long e = System.currentTimeMillis() - s;
//        char a = ' ';

        String[] bs = new String[7];
        bs[0] = "int a:1+2";
        bs[1] = "log a";
        bs[2] = "strfmt y : '%s+  %s', a, a";
        bs[3] = "log y";
        bs[4] = "int c:6";
        bs[5] = "int c:c+2";
        bs[6] = "log c";
        String[] cs = read_file("d:/1.txt");
        /* 1.txt=
        int a:0
        fl c :0
        if c
          log 'hi'
        elsif a
          log 'bye'
        else
          log 'good'
        endif
        fl c:4
        while c
          log 'hi'
          fl c :c-1
        endwh
        */
        //ve.exec_loop(bs, new int[0]);
        ve.exec_loop(cs, new int[0]);
//        System.out.println(e/1000);
        //System.out.println(x);

    }

    static String[] read_file(String fpath) throws FileNotFoundException{
        ArrayList<String> ss = new ArrayList<String>();
        Scanner sc = new Scanner(new File(fpath));
        while (sc.hasNextLine()){
            ss.add(sc.nextLine());
        }
        sc.close();
        int k = ss.size();
        String[] r = new String[k];
        for (int j = 0; j < k; j++){
            r[j] = ss.get(j);

        }
        return r;
    }

}


class Vbenv {

    int blkid = 0;
    int sgid = 1;

    ArrayList<String> subdef = new ArrayList<String>();
    ArrayList<String> wnames = new ArrayList<String>();
    ArrayList<Integer> wsids = new ArrayList<Integer>();
    ArrayList<Integer> wblocks = new ArrayList<Integer>();

    ArrayList<Integer> wints = new ArrayList<Integer>();
    ArrayList<String> wstrs = new ArrayList<String>();
    ArrayList<Double> wflts = new ArrayList<Double>();
    ArrayList<Integer> wtypes = new ArrayList<Integer>();
    ArrayList<Integer> wneids = new ArrayList<Integer>();
    ArrayList<Integer> blks = new ArrayList<Integer>();
    ArrayList<Integer> wait_sids= new ArrayList<Integer>();

    public Vbenv(){

        blks.add(blkid);
       // st_read_addr("a");
    }



    int st_read_addr(String name){

        //System.out.println(this.blks);
        int j = blks.size()-1;

        while (j >= 0){
            int k = wnames.size()-1;
            int cblk = blks.get(j);
            while (k >= 0){
                if (cblk == wblocks.get(k) && wnames.get(k).equals(name)){
                    return k;
                }
                k--;
            }
            j--;
        }
        return -1;
    }

    double expr(String inp) throws Exception{
        ArrayList<Integer> opts = new ArrayList<>();
        ArrayList<Double> nums = new ArrayList<>();
        double fv = 0;
        int j = 0;

        StringBuilder sb = new StringBuilder();
        while (j < inp.length()){
            char ch = inp.charAt(j);
            int chi = (int)ch;
            int cop = 0;
            if (chi == 43){ // +
                cop = 1;
            } else if (chi == 45){ // -
                cop = 2;
            } else if (chi == 42){ // *
                cop = 3;
            } else if (chi == 47){ // /
                cop = 4;
            } else if (chi == 40 ){ // (
                cop = 5; 
            } else if (chi == 41){ // )
                cop = 6; 

            }
            if (cop > 0){
                if (sb.length() > 0){
                    String tm = sb.toString();
                    // System.out.println(tm);
                    int faddr = st_read_addr(tm);
                    if (faddr == -1){
                        fv = Double.parseDouble(tm);
                    }else if (wtypes.get(faddr) == 1){
                        fv = wints.get(faddr);
                    }else if (wtypes.get(faddr) == 2){
                        fv = wflts.get(wints.get(faddr));
                    } else{

                        throw new Exception("figure name error");
                    }

                    opts.add(0);
                    nums.add(fv);
                    sb.delete(0, sb.length());
                }
                opts.add(cop);
            } else{
              sb.append(ch);
            }
            j += 1;

        }
        if (sb.length() > 0){
            String tm = sb.toString();
            int faddr = st_read_addr(tm);
            if (faddr == -1){
                fv = Double.parseDouble(tm);
            }else if (wtypes.get(faddr) == 1){
                fv = wints.get(faddr);
            }else if (wtypes.get(faddr) == 2){
                fv = wflts.get(wints.get(faddr));
            } else{
                int y = 0;
                throw new Exception("figure name error");
            }
            opts.add(0);
            nums.add(fv);
            sb.delete(0, sb.length());
        }

       // System.out.println("@");
        if (opts.size() == 0){
            return nums.get(0);
        }

        ArrayList<Double> hes = new ArrayList<>();
        ArrayList<Double> jis = new ArrayList<>(); 
        ArrayList<Integer> hops = new ArrayList<>();     

        int k = 0;
        double he = 0;
        double ji = 0;
        int op = 1;
        //boolean is_ji = false;
        for (int fop : opts){
            if (fop == 0){

                if (op == 3){
                    ji = ji * nums.get(k);
                } else if (op == 4){
                    ji = ji / nums.get(k);
                } else if (op == 1){
                    ji = nums.get(k);
                } else if (op == 2){
                    ji = -1*nums.get(k);
                }
                k++;
            } else if (fop == 5){

                if (op == 1 || op == 2){
                    hes.add(he);
                    jis.add(0.0);
                } else if (op == 3 || op == 4){
                    hes.add(he);
                    jis.add(ji);
                }
                hops.add(op);
                he = 0;
                ji = 0;
                op = 1;
            } else if (fop == 6) {
                he += ji;
                int m = jis.size()-1;
                double aji = jis.get(m);
                jis.remove(m);
                m = hops.size()-1;
                int bop = hops.get(m);
                hops.remove(m);
                if (bop == 1){
                    ji = he;
                } else if (bop == 2){
                    ji = -1*he;
                } else if (bop == 3){
                    ji = aji * he;
                } else if (bop == 4){
                    ji = aji / he;
                }
                m = hes.size()-1;
                he = hes.get(m);
                hes.remove(m);
            } else if (fop == 1 || fop == 2 ){
                op = fop;
                he += ji;
            } else if (fop == 3 || fop == 4 ){
                op = fop;
            }
       }
        he += ji;


        return he;
    }


    // 分词功能
    String[] fenci (String inp){

        ArrayList<String> syms = new ArrayList<>();
        int y3 = 0;
        char yy;

        StringBuilder sb = new StringBuilder();
        boolean isstr = false;

        while (y3 < inp.length()){
            yy = inp.charAt(y3);
            if (yy == '\''){

                if (isstr) {
                    isstr = false;
                    if (sb.length() > 0){
                        String tmp1 = "$" + sb.toString();
                        syms.add(tmp1); 
                        sb.delete(0, sb.length());
                    }
                } else{
                    isstr = true;
                }
            }else if (isstr){
                sb.append(yy);
            } else if (yy == ',') { 
                if (sb.length() > 0){
                    syms.add(sb.toString());
                    sb.delete(0, sb.length());
                }
            } else if (yy == ':'){
                 if (sb.length() > 0){
                    syms.add(sb.toString());
                    sb.delete(0, sb.length());
                }
                syms.add(":");



            } else if (yy == ' ') { 
                if (sb.length() > 0){
                    syms.add(sb.toString());
                    sb.delete(0, sb.length());
                }
            } else {
                sb.append(yy);
            }
            y3++;
        }



        if (sb.length() > 0){
            syms.add(sb.toString());
        }


        int sz = syms.size();
        String[] r = new String[sz];
        for (int cyy = 0; cyy < sz; cyy++){
            r[cyy] = syms.get(cyy);
        }
        return r;
    }

    boolean choose_cond(String inp){
        if (inp.charAt(0) == '$'){ 
            return true;
        } else {
            int b = st_read_addr(inp);
            if (b == -1) {
                try{
                    double c =  Double.parseDouble(inp);
                    if (c == 0){
                        return false;
                    } else {
                        return true;
                    }
                } catch (NumberFormatException e){
                    return false;
                 }
            }  else {
                int wtype = wtypes.get(b);
                if (wtype == 1){
                    if (wints.get(b) == 0){
                        return false;
                    } else {
                        return true;
                    }
                } else if (wtype == 2){
                    if (wflts.get(wints.get(b)) == 0){
                        return false;
                    } else {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    String side_fn_str(String[] fpr){

        return "";
    }
    double side_fn_fl(String[] fpr){
        if (fpr[0].equals("pow")){

        }
        return 0;
    }
    int side_fn_int(String[] fpr){

        return 0;
    }

    void side_fn_null(String[] fpr) {

    }

    int user_fsub(String fn, int[] wsids3) throws Exception{
        int k = subdef.size()-1;
        String fn2 = "@" + fn;
        boolean ex = false;
        while (k >= 0){
            if (subdef.get(k).equals(fn2)){
                ex = true;
                break;
            }
            k--;
        }
        ArrayList<String> b = new ArrayList<>();
        while (ex){
            k++;
            String cur = subdef.get(k);
            String[] fc = fenci(cur);
            if (fc[0].equals("@end")){
                ex = false;
            } else {
                b.add(cur);
            }
        }
        String[] itrs = new String[b.size()] ;
        for (k = 0; k < b.size(); k++){
            itrs[k] = b.get(k);
        }
        wait_sids.add(-1);
        exec_loop(itrs, wsids3);
        int r = -1;
        k = wait_sids.size()-1;
        r = wait_sids.get(k);

        wait_sids.remove(k);
        return r;
    }


    void exec_loop(String[] itrs, int[] wsids3) throws Exception {
        int j = 0;
        int ifnum = 1; // 尾数为1可以执行分支,尾数2不执行分支
        ArrayList<Integer> jmp_itrs = new ArrayList<Integer>();
        boolean record_sub = false;
        String fn;
        boolean cd;
        while (j < itrs.length){
            String[] fc = fenci(itrs[j]);
           // System.out.println(String.join("-", fc));
            if (fc.length > 0) {
                String cmd = fc[0];
                //System.out.println("sub".equals("sub"));
                if (cmd.equals("sub")){ 
                    fn = "@" + fc[1];
                    subdef.add(fn);
                    record_sub = true;
                    j++;
                } else if (cmd.equals("endsub")){
                    subdef.add("@end");
                    record_sub = false;
                    j++;
                } else if (record_sub){
                    subdef.add(itrs[j]);
                    j++;
                } else {
                    if (cmd.equals("if")){
                        if (ifnum %10 == 1){
                            cd = choose_cond(fc[1]);
                            if (cd){
                                ifnum = ifnum*10+1;
                            } else {
                                ifnum = ifnum*10+2;
                            }
                        } 
                        j++;
                    } else if (cmd.equals("elsif")){
                        if (ifnum %10 == 1){
                            ifnum = (int) ifnum/10;
                            ifnum = ifnum*10+2;

                        } else {
                            cd = choose_cond(fc[1]);
                            if (cd){
                                ifnum = (int) ifnum/10;
                                ifnum = ifnum*10+1;
                            } 
                        } 
                        j++;
                    } else if (cmd.equals("else")){
                        if (ifnum %10 == 1){
                            ifnum = (int) ifnum/10;
                            ifnum = ifnum*10+2;

                        } 
                        j++;
                    } else if (cmd.equals("endif")){
                        ifnum = (int)(ifnum/10);
                        j++;

                    } else{
                        if (ifnum %10 == 1){ 
                            if (cmd.equals("while")){
                               cd = choose_cond(fc[1]) ;
                               if (cd == false){
                                   int find_newh = 1;
                                   while (find_newh > 0){
                                       j++;
                                       String[] fcc = fenci(itrs[j]);
                                       if (fcc[0].equals("endwh")){
                                           find_newh--;
                                       } else if (fcc[0].equals("while")){
                                           find_newh++;
                                       }
                                   }
                                   j++;
                               } else {
                                   jmp_itrs.add(j);
                                   j++;
                               }
                            } else if (cmd.equals("endwh")){
                                int k = jmp_itrs.size() - 1;
                                j = jmp_itrs.get(k);
                                jmp_itrs.remove(k);
                            } else {
                                exec_one(itrs[j], wsids3);
                                j++;
                            }
                        }else{
                                j++;
                        }
                    } 
                }
            } else {
                j++;
            }
        }
    }

    void exec_one(String inp, int[] wsids3) throws Exception{
        String[] fc = fenci(inp) ;
       //System.out.println(String.join("-", fc));
        String cmd = fc[0];
        if (cmd.equals("str")){
            if (fc[2].equals(":")){
                if (fc[3].charAt(0) == '$'){
                    int b = st_read_addr(fc[1]);
                    String fb = fc[3].substring(1);
                    if (b == -1){

                        wnames.add(fc[1]);
                        sgid++;
                        wsids.add(sgid);
                        wblocks.add(blks.get(blks.size()-1));
                        wints.add(wstrs.size());
                        wstrs.add(fb);
                        wtypes.add(3);
                    } else{
                        wints.set(b, wstrs.size());
                        wstrs.add(fb);
                        wtypes.set(b,3);
                    }
                }
            } else if (fc[2].equals("fn") && fc[3].equals(":")){
                String[] fpr = new String[fc.length-4];
                for (int k = 4; k < fc.length; k++){
                    fpr[k-4] = fc[k];
                }
                String fb = side_fn_str(fpr);
                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wstrs.size());
                    wstrs.add(fb);
                    wtypes.add(3);
                } else{
                    wints.set(b, wstrs.size());
                    wstrs.add(fb);
                    wtypes.set(b,3);
                }

            } else if (fc[2].equals("fsub") && fc[3].equals(":")){
                blkid++;
                blks.add(blkid);
                int[] wsids2 = new int[fc.length-5];
                for (int k = 5; k < fc.length; k++){
                    wnames.add("");
                    sgid++;
                    wsids.add(sgid);
                    wsids2[k-5] = sgid;
                    wblocks.add(blkid);
                    wints.add(wstrs.size());
                    wstrs.add(fc[k]);
                    if (fc[k].charAt(0) == '$'){
                        wtypes.add(3);
                    }else {
                        wtypes.add(0);
                    }
                }
                int wrid = user_fsub(fc[4], wsids2);
                blks.remove(blks.size()-1);
                String fb=  wstrs.get(wints.get(wrid));

                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wstrs.size());
                    wstrs.add(fb);
                    wtypes.add(3);
                } else{
                    wints.set(b, wstrs.size());
                    wstrs.add(fb);
                    wtypes.set(b,3);
                }        

            }
        } else if ( cmd.equals("fl")){
            if (fc[2].equals(":")){
                double fv = expr(fc[3]);
                int b = st_read_addr(fc[1]);
                if (b == -1){
                      wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wflts.size());
                    wflts.add(fv);
                    wtypes.add(2);
                } else{
                    wints.set(b, wflts.size());
                    wflts.add(fv);
                    wtypes.set(b,2);
                }
            } else if (fc[2].equals("fn") && fc[3].equals(":")){
                String[] fpr = new String[fc.length-4];
                for (int k = 4; k < fc.length; k++){
                    fpr[k-4] = fc[k];
                }
                double fb = side_fn_fl(fpr);
                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wflts.size());
                    wflts.add(fb);
                    wtypes.add(2);
                } else{
                    wints.set(b, wflts.size());
                    wflts.add(fb);
                    wtypes.set(b,2);
                }

            } else if (fc[2].equals("fsub") && fc[3].equals(":")){
                blkid++;
                blks.add(blkid);
                int[] wsids2 = new int[fc.length-5];
                for (int k = 5; k < fc.length; k++){
                    wnames.add("");
                    sgid++;
                    wsids.add(sgid);
                    wsids2[k-5] = sgid;
                    wblocks.add(blkid);
                    wints.add(wstrs.size());
                    wstrs.add(fc[k]);
                    if (fc[k].charAt(0) == '$'){
                        wtypes.add(3);
                    }else {
                        wtypes.add(0);
                    }
                }
                int wrid = user_fsub(fc[4], wsids2);
                blks.remove(blks.size()-1);
                double fb=wflts.get(wints.get(wrid));

                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wflts.size());
                    wflts.add(fb);
                    wtypes.add(2);
                } else{
                    wints.set(b, wflts.size());
                    wflts.add(fb);
                    wtypes.set(b,2);
                }        
            }
        } else if (cmd.equals("int")){
            if (fc[2].equals(":")){
                int fv = (int) expr(fc[3]);
                int b = st_read_addr(fc[1]);
                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(fv);
                    wtypes.add(1);
                } else{
                    wints.set(b, fv);
                    wtypes.set(b,1);
                }
             } else if (fc[2].equals("fn") && fc[3].equals(":")){
                String[] fpr = new String[fc.length-4];
                for (int k = 4; k < fc.length; k++){
                    fpr[k-4] = fc[k];
                }
                int fb = side_fn_int(fpr);
                int b = st_read_addr(fc[1]);

                if (b == -1){


                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(fb);
                    wtypes.add(1);
                } else{
                    wints.set(b, fb);
                    wtypes.set(b,1);
                }

            } else if (fc[2].equals("fsub") && fc[3].equals(":")){
                blkid++;
                blks.add(blkid);
                int[] wsids2 = new int[fc.length-5];
                for (int k = 5; k < fc.length; k++){
                    wnames.add("");
                    sgid++;
                    wsids.add(sgid);
                    wsids2[k-5] = sgid;
                    wblocks.add(blkid);
                    wints.add(wstrs.size());
                    wstrs.add(fc[k]);
                    if (fc[k].charAt(0) == '$'){
                        wtypes.add(3);
                    }else {
                        wtypes.add(0);
                    }
                }
                int wrid = user_fsub(fc[4], wsids2);
                blks.remove(blks.size()-1);
                int fb=wints.get(wrid);

                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(fb);
                    wtypes.add(1);
                } else{
                    wints.set(b, fb);
                    wtypes.set(b,1);
                }        
            }    
        } else if (cmd.equals("fn") && fc[1].equals(":")){
            String[] fpr = new String[fc.length-2];
            for (int k = 2; k < fc.length; k++){
                fpr[k-2] = fc[k];
            }
            side_fn_null(fpr);
        } else if (cmd.equals("fsub") && fc[1].equals(":")){
            blkid++;
            blks.add(blkid);
            int[] wsids2 = new int[fc.length-3];
            for (int k = 3; k < fc.length; k++){
                wnames.add("");
                sgid++;
                wsids.add(sgid);
                wsids2[k-3] = sgid;
                wblocks.add(blkid);
                wints.add(wstrs.size());

                if (fc[k].charAt(0) == '$'){
                    wtypes.add(3);
                    wstrs.add(fc[k].substring(1));
                }else {
                    wtypes.add(0);
                    wstrs.add(fc[k]);
                }
            }
            user_fsub(fc[2], wsids2);
            blks.remove(blks.size()-1);
        }   else if (cmd.equals("args")){
            if ((fc.length-1)/2 <= wsids3.length){
                int k = 1;
                while (k <= (int)(fc.length/2)){
                    int m = wnames.size()-1;
                    boolean f = false;
                    while (m >= 0){
                        if (wsids3[k-1] == wsids.get(m)){
                            wnames.set(m, fc[k*2]);
                            if (fc[2*k-1].equals("str")){
                                wtypes.set(m, 3);
                            } else if (fc[2*k-1].equals("fl")){
                                wtypes.set(m, 2);
                                double y5 = Double.parseDouble(wstrs.get(m));
                                wints.set(m, wflts.size());
                                wflts.add(y5);


                            } else if (fc[2*k-1].equals("int")){
                                wtypes.set(m, 1);
                                int y5 = Integer.parseInt(wstrs.get(m));
                                wints.set(m, y5);

                            }
                            f = true;
                            break;
                        }
                        m--;
                    }
                    if (f){
                        k++;
                    } else{
                        throw new Exception("wsids3 error");
                    }
                }
            }
        } else if (cmd.equals("ret")){
            // 返回数组索引地址
            int wpr = blks.get(blks.size()-1);
            int k = wnames.size()-1;
            while (k >= 0){
                if (wblocks.get(k) == wpr && wnames.get(k).equals(fc[1])){
                    wait_sids.set(wait_sids.size()-1, k);
                    break;
                }
                k--;
            }


        } else if (cmd.equals("log")){
            if (fc[1].charAt(0) == '$'){
                System.out.println(fc[1].substring(1));
            } else {
                int k = wnames.size()-1;
                while (k >= 0){
                    if (wnames.get(k).equals(fc[1])){
                        int wtp = wtypes.get(k);
                        if ( wtp== 1){
                            System.out.println(wints.get(k));
                        } else if (wtp == 2){
                            System.out.println(wflts.get(wints.get(k)));
                        }else if (wtp == 3){
                            System.out.println(wstrs.get(wints.get(k)));
                        }
                    }
                    k--;
                }
            }
        }else if (cmd.equals("strfmt")){
            if (fc[2].equals(":") && fc[3].charAt(0) == '$'){
                int y = 4;
                String fb = fc[3].substring(1);
                int g = fb.indexOf("%s");
                String fe = "";
                while (g >= 0){
                    int k = wnames.size()-1;
                    while (k >= 0){
                        if (wnames.get(k).equals(fc[y])){
                            int wtp = wtypes.get(k);
                            if ( wtp== 1){
                                fe = wints.get(k).toString();
                            } else if (wtp == 2){
                                fe = wflts.get(wints.get(k)).toString();
                            }else if (wtp == 3){
                                fe = wstrs.get(wints.get(k));
                            }

                            fb = fb.substring(0, g) + fe + fb.substring(g+2);
                            y++;
                        }
                        k--;
                    }
                    //System.out.println(fb);
                    g = fb.indexOf("%s");
                }
                int b = st_read_addr(fc[1]);

                if (b == -1){

                    wnames.add(fc[1]);
                    sgid++;
                    wsids.add(sgid);
                    wblocks.add(blks.get(blks.size()-1));
                    wints.add(wstrs.size());
                    wstrs.add(fb);
                    wtypes.add(3);
                } else{
                    wints.set(b, wstrs.size());
                    wstrs.add(fb);
                    wtypes.set(b,3);
                }    
            }

        }
        else {
            System.out.println("skip cmd=" + cmd);
            //throw new Exception("unknown command");
        }

    }

}

不错~可以建立个 github 项目,然后把简介和链接贴过来。

更新啦支持嵌套 while 和 if

更新啦支持嵌套 while 和 if

需要 登录 后方可回复, 如果你还没有账号请 注册新账号