ucscompiler.pas

来自「本Delphi项目文件为本人在一个Pascal-s(子集)源代码基础上完成的。本」· PAS 代码 · 共 1,455 行 · 第 1/5 页

PAS
1,455
字号
                                    end else begin //array selector
                                    if sy<>lbrack then CCLex.error(11);
                                    repeat
                                        CCLex.Insymbol;
                                        expression(fsys+[comma,rbrack],x);
                                        if v.typ<>arrays
                                        then CCLex.error(28)
                                        else begin
                                            a:= v.ref;
                                            if atab[a].inxtyp<>x.typ
                                            then CCLex.error(26)
                                            else if atab[a].elsize=1
                                                then emit1(20,a)
                                                else emit1(21,a);
                                            v.typ:= atab[a].eltyp;
                                            v.ref:= atab[a].elref
                                        end
                                    until sy<>comma;
                                    if sy = rbrack
                                    then CCLex.Insymbol
                                    else begin
                                        CCLex.error(12);
                                        if sy=rparent then CCLex.Insymbol
                                    end
                                end
                            until not (sy in [lbrack,lparent,period]);
                            test(fsys,[],6);
                        end;//selector

                        procedure call (fsys:symset;i:integer);
                        var x: item;
                            lastp,cp,K : integer;
                        begin
                            emit1(18,i); {mark stack}
                            lastp:= btab[tab[i].ref].lastpar;
                            cp:=i;
                            if sy= lparent
                            then begin //actual parameter list
                                repeat
                                    CCLex.Insymbol;
                                    if cp>= lastp
                                    then CCLex.error(39)
                                    else begin
                                        cp:= cp+1;
                                        if tab[cp].normal
                                        then begin
                                            expression(fsys+[comma,colon,rparent],x);
                                            if x.typ=tab[cp].typ
                                            then begin
                                                if x.ref< tab[cp].ref
                                                then CCLex.error(36)
                                                else if x.typ = arrays
                                                    then emit1(22,atab[x.ref].size)
                                                    else if x.typ=records
                                                        then emit1(22,btab[x.ref].vsize)
                                            end  else if (x.typ=ints) and (tab[cp].typ=reals)
                                                    then emit1(26,0)
                                                    else if     x.typ<>notyp then CCLex.error(36);
                                            end else begin //variable parameter
                                                if sy<>ident
                                                then CCLex.error(2)
                                                else begin k:= loc(id);
                                                CCLex.Insymbol;
                                                if k<>0
                                                then begin
                                                    if tab[k].obj<>vvariable then CCLex.error(37);
                                                    x.typ:= tab[k].typ;
                                                    x.ref:= tab[k].ref;
                                                    if tab[k].normal
                                                    then emit2(0,tab[k].lev,tab[k].adr)
                                                    else emit2(1,tab[k].lev,tab[k].adr);
                                                    if sy in [lbrack,lparent,period]
                                                    then selector(fsys+[comma,colon,rparent],x);
                                                    if (x.typ<>tab[cp].typ)or (x.ref<>tab[cp].ref)
                                                    then CCLex.error(36)
                                                end
                                            end
                                        end;//variable parameter
                                    end;
                                    test([comma,rparent],fsys,6);
                                until sy<>comma;
                                if sy= rparent then CCLex.Insymbol else CCLex.error(4)
                            end;
                            if cp< lastp then CCLex.error(39);//too few parameters
                            emit1(19,btab[tab[i].ref].psize -1);
                            if tab[i].lev< level then emit2(3,tab[i].lev,level)
                        end;//call

                        function resulttype(A,B:types):types;
                        begin
                            if (a>reals) or(b>reals)
                            then begin
                                CCLex.error(33);
                                resulttype:= notyp;
                            end else if (a=notyp) or(b=notyp)
                                then    resulttype:= notyp
                                else if a=ints
                                     then if b=ints
                                          then resulttype:= ints
                                          else begin
                                            resulttype:= reals; emit1(26,1)
                                          end
                                     else begin
                                        resulttype:= reals;
                                        if b=ints then emit1(26,0)
                                     end
                        end;//resulttype

                        procedure expression(fsys:symset; var X:item);
                        var y:item;
                            op: symbol;

                        procedure simpleexpression(fsys: symset; var x:item);
                        var y:item;
                            op: symbol;
                            procedure   term(fsys:symset;var x:item);
                            var     y:item;
                                op:symbol;
                                ts:typset;
                            procedure   factor(fsys:symset;var x:item);
                                var i,f:integer;
                                procedure standfct(n:integer);
                                    var ts:typset;
                                    begin
                                        if sy=lparent
                                        then CCLex.Insymbol
                                        else CCLex.error(9);
                                        if n<17
                                        then begin
                                            expression(fsys+[rparent],x);
                                            case n of
                                        {abs,sqr} 0,2:begin
                                                        ts:= [ints,reals];
                                                        tab[i].typ:= x.typ;
                                                        if x.typ =reals then n:= n+1;
                                                      end;
                                                4,5://odd ,chr
                                                    ts:= [ints];
                                                6://odr
                                                    ts:= [ints,bools,chars];
                                                7,8: //succ,pred
                                                    begin
                                                        ts:= [ints,bools,chars];
                                                        tab[i].typ:= x.typ
                                                    end;
                                                9..16://round,trunc,...,sin,cos
                                                    begin
                                                        ts:= [ints,reals];
                                                        if x.typ=ints then emit1(26,0)
                                                    end;
                                                end;//case
                                                    if x.typ in ts
                                                    then emit1(8,n)
                                                    else if x.typ<>notyp
                                                        then  CCLex.error(48);
                                                    end else begin  {n in [17,18]}
                                                      if sy<>ident
                                                      then CCLex.error(2)
                                                      else if id<>'input'
                                                            then CCLex.error(0)

                                                            else CCLex.Insymbol;
                                                      emit1(8,n);
                                                    end;
                                                    x.typ:= tab[i].typ;
                                                    if sy=rparent then CCLex.Insymbol else CCLex.error(4)
                                                end;{standfct}
                                        begin {factor}

                                            x.typ:= notyp;
                                            x.ref:= 0;
                                            test(facbegsys,fsys,58);
                                            while sy in facbegsys do
                                            begin
                                                if sy=ident
                                                then begin
                                                    i := loc(id);
                                                    CCLex.Insymbol;
                                                    with tab[i] do
                                                        case obj of
                                                        konstant: begin
                                                                       x.typ:= typ;
                                                                       x.ref:= 0;
                                                                       if x.typ=reals
                                                                       then emit1(25,adr)
                                                                       else emit1(24,adr)
                                                                    end;
                                                        vvariable: begin
                                                                       x.typ:= typ;
                                                                       x.ref:= ref;
                                                                       if sy in [lbrack,lparent,period]
                                                                       then begin
                                                                        if normal then f:=0 else f:=1;
                                                                        emit2(f,lev,adr);
                                                                        selector(fsys,x);
                                                                        if x.typ in stantyps then emit(34)
                                                                       end else begin
                                                                         if x.typ   in stantyps
                                                                         then if normal
                                                                            then    f:=1
                                                                            else    f:=2
                                                                         else if normal then f:=0 else f:=1;
                                                                         emit2(f,lev,adr)
                                                                       end
                                                                    end;
                                                        typel,prozedure:CCLex.error(44);
                                                        funktion:begin
                                                                    x.typ:=typ;
                                                                    if lev<>0
                                                                    then call(fsys,i)
                                                                    else standfct(adr)
                                                                end
                                                        end {case ,with}
                                                    end else if sy in [charcon,intcon,realcon]
                                                            then    begin
                                                                if sy=realcon
                                                                then begin
                                                                    x.typ:= reals;
                                                                    enterreal(CCLex.rnum);
                                                                    emit1(25,c1)
                                                                end else begin
                                                                    if sy= charcon
                                                                    then x.typ:= chars
                                                                    else x.typ:= ints;
                                                                    emit1(24,inum)
                                                                end;
                                                                x.ref:= 0;
                                                                CCLex.Insymbol
                                                            end else if sy=lparent
                                                                    then    begin
                                                                        CCLex.Insymbol;
                                                                        expression(fsys+[rparent],x);
                                                                        if sy= rparent
                                                                        then CCLex.Insymbol
                                                                        else CCLex.error(4)
                                                                    end else if sy=notsy
                                                                            then begin
                                                                                CCLex.Insymbol;
                                                                                factor(fsys,x);
                                                                                if x.typ=bools
                                                                                then emit(35)
                                                                                else if x.typ<>notyp
                                                                                    then    CCLex.error(32)
                                                                                end;
                                                            test(fsys,facbegsys,6)
                                                    end //while
                                              end;//factor

                            begin //term
                                factor(fsys+[times,rdiv,idiv,imod,andsy],x);
                                while sy in[times,rdiv,idiv,imod,andsy] do
                                begin
                                    op:= sy;
                                    CCLex.Insymbol;
                                    factor(fsys+[times,rdiv,idiv,imod,andsy],y);
                                    if op=times
                                    then begin
                                        x.typ:= resulttype(x.typ,y.typ);
                                        case x.typ of
                                         notyp:;
                                         ints: emit(57);
                                         reals: emit(60);
                                        end
                                    end else if op=rdiv
                                            then begin
                                                if x.typ = ints
                                                then begin
                                                    emit1(26,1);
                                                    X.TYP:=reals;
                                                end;
                                                if y.typ=ints
                                                then begin
                                                    emit1(26,0);
                                                    y.typ:= reals;
                                                end;
                                                if (x.typ=reals) and (y.typ=reals)
                                                then emit(61)
                                                else begin
                                                    if(x.typ<>notyp) and(y.typ<>notyp)
                                                    then  CCLex.error(33);
                                                    x.typ:=notyp;
                                                end
                                            end else if op=andsy
                                                then begin
                                                    if (x.typ=bools)and(y.typ=bools)
                                                    then emit(56)
                                                    else begin
                                                     if(x.typ<>notyp) and(y.typ<>notyp)
                                                     then CCLex.error(32);
                                                     x.typ:= notyp
                                                    end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?