|
@@ -2970,651 +2970,627 @@ Listing:
|
|
|
2952 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
2952 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
2953 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
2953 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
2954 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
2954 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2955 QbeGen.ElemLoad(q, t, q2);
|
|
|
|
|
- 2956 QbeGen.CopyOp(q2, q)
|
|
|
|
|
- 2957 END
|
|
|
|
|
- 2958 END; .) ]
|
|
|
|
|
- 2959 (. IF called THEN
|
|
|
|
|
- 2960 astCur := astRes
|
|
|
|
|
- 2961 ELSIF astCall THEN
|
|
|
|
|
- 2962 astCur := astBrace
|
|
|
|
|
- 2963 ELSE astCur := astD
|
|
|
|
|
- 2964 END;
|
|
|
|
|
- 2965 astIsLit := TRUE;
|
|
|
|
|
- 2966 IF NOT called
|
|
|
|
|
- 2967 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
- 2968 (* bare zero-arg function
|
|
|
|
|
- 2969 call (parentheses may be
|
|
|
|
|
- 2970 omitted); a proper or
|
|
|
|
|
- 2971 parameterised proc here
|
|
|
|
|
- 2972 is 230 *)
|
|
|
|
|
- 2973 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
- 2974 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
- 2975 SymTab.InvalidType) THEN
|
|
|
|
|
- 2976 QbeGen.Mangled(qn,
|
|
|
|
|
- 2977 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2978 QbeGen.CallBegin(qm0,
|
|
|
|
|
- 2979 SymTab.ProcRes(qn),
|
|
|
|
|
- 2980 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 2981 SymTab.IsExternal(qn));
|
|
|
|
|
- 2982 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
- 2983 astCur := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 2984 AST.SetChild(astCur, 0, astD);
|
|
|
|
|
- 2985 t := SymTab.ProcRes(qn)
|
|
|
|
|
- 2986 ELSE
|
|
|
|
|
- 2987 (* procedure used as a
|
|
|
|
|
- 2988 value (assign to a
|
|
|
|
|
- 2989 procedure variable):
|
|
|
|
|
- 2990 its code address *)
|
|
|
|
|
- 2991 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
- 2992 QbeGen.Mangled(qn,
|
|
|
|
|
- 2993 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2994 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
- 2995 END
|
|
|
|
|
- 2996 END; .)
|
|
|
|
|
- 2997 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
- 2998 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
- 2999 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
- 3000 isU := FALSE; .)
|
|
|
|
|
- 3001 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
- 3002 isStr := TRUE;
|
|
|
|
|
- 3003 isU := FALSE;
|
|
|
|
|
- 3004 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 3005 dt := SymTab.CharType();
|
|
|
|
|
- 3006 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
- 3007 qd)
|
|
|
|
|
- 3008 ELSE
|
|
|
|
|
- 3009 dt := SymTab.NewStr();
|
|
|
|
|
- 3010 QbeGen.DeclStr(s, qd);
|
|
|
|
|
- 3011 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 3012 END;
|
|
|
|
|
- 3013 dk := -1;
|
|
|
|
|
- 3014 qn[0] := CHR(0); .)
|
|
|
|
|
- 3015 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
- 3016 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
- 3017 uok);
|
|
|
|
|
- 3018 isStr := FALSE;
|
|
|
|
|
- 3019 IF NOT uok THEN
|
|
|
|
|
- 3020 SemError(234);
|
|
|
|
|
- 3021 dt := SymTab.InvalidType
|
|
|
|
|
- 3022 ELSIF isU THEN
|
|
|
|
|
- 3023 (* one codepoint: a UCHAR;
|
|
|
|
|
- 3024 LEN is 1, HIGH is 0 *)
|
|
|
|
|
- 3025 dt := SymTab.UCharType();
|
|
|
|
|
- 3026 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
- 3027 ELSE
|
|
|
|
|
- 3028 dt := SymTab.NewUStr();
|
|
|
|
|
- 3029 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 3030 END;
|
|
|
|
|
- 3031 dk := -1;
|
|
|
|
|
- 3032 qn[0] := CHR(0); .) )
|
|
|
|
|
- 3033 ")"
|
|
|
|
|
- 3034 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3035 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3036 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
|
|
- 3037 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3038 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
|
|
- 3039 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3040 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3041 IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3042 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
- 3043 (* UString: the count is
|
|
|
|
|
- 3044 the descriptor header *)
|
|
|
|
|
- 3045 IF isHigh THEN
|
|
|
|
|
- 3046 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
- 3047 QbeGen.DecQ(qr)
|
|
|
|
|
- 3048 ELSE
|
|
|
|
|
- 3049 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
- 3050 END;
|
|
|
|
|
- 3051 t := SymTab.IntType();
|
|
|
|
|
- 3052 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3053 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3054 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
- 3055 (* single UCHAR codepoint *)
|
|
|
|
|
- 3056 IF isHigh THEN
|
|
|
|
|
- 3057 QbeGen.CopyOp("0", qr)
|
|
|
|
|
- 3058 ELSE
|
|
|
|
|
- 3059 QbeGen.CopyOp("1", qr)
|
|
|
|
|
|
|
+ 2955 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2956 END
|
|
|
|
|
+ 2957 END; .) ]
|
|
|
|
|
+ 2958 (. IF called THEN
|
|
|
|
|
+ 2959 astCur := astRes
|
|
|
|
|
+ 2960 ELSIF astCall THEN
|
|
|
|
|
+ 2961 astCur := astBrace
|
|
|
|
|
+ 2962 ELSE astCur := astD
|
|
|
|
|
+ 2963 END;
|
|
|
|
|
+ 2964 astIsLit := TRUE;
|
|
|
|
|
+ 2965 IF NOT called
|
|
|
|
|
+ 2966 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
+ 2967 (* bare zero-arg function
|
|
|
|
|
+ 2968 call (parentheses may be
|
|
|
|
|
+ 2969 omitted); a proper or
|
|
|
|
|
+ 2970 parameterised proc here
|
|
|
|
|
+ 2971 is 230 *)
|
|
|
|
|
+ 2972 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
+ 2973 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
|
|
+ 2974 t := SymTab.ProcRes(qn);
|
|
|
|
|
+ 2975 QbeGen.CopyOp("@", q);
|
|
|
|
|
+ 2976 astCur := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 2977 AST.SetChild(astCur, 0, astD)
|
|
|
|
|
+ 2978 ELSE
|
|
|
|
|
+ 2979 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
+ 2980 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2981 END
|
|
|
|
|
+ 2982 END; .)
|
|
|
|
|
+ 2983 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
+ 2984 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
+ 2985 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
+ 2986 isU := FALSE; .)
|
|
|
|
|
+ 2987 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
+ 2988 isStr := TRUE;
|
|
|
|
|
+ 2989 isU := FALSE;
|
|
|
|
|
+ 2990 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 2991 dt := SymTab.CharType();
|
|
|
|
|
+ 2992 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
+ 2993 qd)
|
|
|
|
|
+ 2994 ELSE
|
|
|
|
|
+ 2995 dt := SymTab.NewStr();
|
|
|
|
|
+ 2996 QbeGen.DeclStr(s, qd);
|
|
|
|
|
+ 2997 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 2998 END;
|
|
|
|
|
+ 2999 dk := -1;
|
|
|
|
|
+ 3000 qn[0] := CHR(0); .)
|
|
|
|
|
+ 3001 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
+ 3002 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
+ 3003 uok);
|
|
|
|
|
+ 3004 isStr := FALSE;
|
|
|
|
|
+ 3005 IF NOT uok THEN
|
|
|
|
|
+ 3006 SemError(234);
|
|
|
|
|
+ 3007 dt := SymTab.InvalidType
|
|
|
|
|
+ 3008 ELSIF isU THEN
|
|
|
|
|
+ 3009 (* one codepoint: a UCHAR;
|
|
|
|
|
+ 3010 LEN is 1, HIGH is 0 *)
|
|
|
|
|
+ 3011 dt := SymTab.UCharType();
|
|
|
|
|
+ 3012 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
+ 3013 ELSE
|
|
|
|
|
+ 3014 dt := SymTab.NewUStr();
|
|
|
|
|
+ 3015 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 3016 END;
|
|
|
|
|
+ 3017 dk := -1;
|
|
|
|
|
+ 3018 qn[0] := CHR(0); .) )
|
|
|
|
|
+ 3019 ")"
|
|
|
|
|
+ 3020 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3021 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3022 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
|
|
+ 3023 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3024 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
|
|
+ 3025 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3026 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3027 IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3028 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
+ 3029 (* UString: the count is
|
|
|
|
|
+ 3030 the descriptor header *)
|
|
|
|
|
+ 3031 IF isHigh THEN
|
|
|
|
|
+ 3032 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
+ 3033 QbeGen.DecQ(qr)
|
|
|
|
|
+ 3034 ELSE
|
|
|
|
|
+ 3035 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
+ 3036 END;
|
|
|
|
|
+ 3037 t := SymTab.IntType();
|
|
|
|
|
+ 3038 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3039 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3040 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
+ 3041 (* single UCHAR codepoint *)
|
|
|
|
|
+ 3042 IF isHigh THEN
|
|
|
|
|
+ 3043 QbeGen.CopyOp("0", qr)
|
|
|
|
|
+ 3044 ELSE
|
|
|
|
|
+ 3045 QbeGen.CopyOp("1", qr)
|
|
|
|
|
+ 3046 END;
|
|
|
|
|
+ 3047 t := SymTab.IntType();
|
|
|
|
|
+ 3048 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3049 ELSIF isStr THEN
|
|
|
|
|
+ 3050 (* fold: content length at
|
|
|
|
|
+ 3051 compile time *)
|
|
|
|
|
+ 3052 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 3053 c1 := 1
|
|
|
|
|
+ 3054 ELSE
|
|
|
|
|
+ 3055 c1 :=
|
|
|
|
|
+ 3056 SymTab.StrLen(s) - 2
|
|
|
|
|
+ 3057 END;
|
|
|
|
|
+ 3058 IF isHigh THEN
|
|
|
|
|
+ 3059 DEC(c1)
|
|
|
3060 END;
|
|
3060 END;
|
|
|
- 3061 t := SymTab.IntType();
|
|
|
|
|
- 3062 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3063 ELSIF isStr THEN
|
|
|
|
|
- 3064 (* fold: content length at
|
|
|
|
|
- 3065 compile time *)
|
|
|
|
|
- 3066 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 3067 c1 := 1
|
|
|
|
|
- 3068 ELSE
|
|
|
|
|
- 3069 c1 :=
|
|
|
|
|
- 3070 SymTab.StrLen(s) - 2
|
|
|
|
|
- 3071 END;
|
|
|
|
|
- 3072 IF isHigh THEN
|
|
|
|
|
- 3073 DEC(c1)
|
|
|
|
|
- 3074 END;
|
|
|
|
|
- 3075 QbeGen.IntStr(c1, qr);
|
|
|
|
|
- 3076 t := SymTab.IntType();
|
|
|
|
|
- 3077 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3078 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3079 t := SymTab.InvalidType;
|
|
|
|
|
- 3080 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3081 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 3082 SymTab.ClArray THEN
|
|
|
|
|
- 3083 SemError(217);
|
|
|
|
|
- 3084 t := SymTab.InvalidType;
|
|
|
|
|
- 3085 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3086 ELSE
|
|
|
|
|
- 3087 IF isHigh THEN
|
|
|
|
|
- 3088 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 3089 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
- 3090 ELSE
|
|
|
|
|
- 3091 QbeGen.IntStr(
|
|
|
|
|
- 3092 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
- 3093 END
|
|
|
|
|
- 3094 ELSE
|
|
|
|
|
- 3095 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 3096 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
- 3097 ELSE
|
|
|
|
|
- 3098 QbeGen.IntStr(VAL(
|
|
|
|
|
- 3099 INTEGER,
|
|
|
|
|
- 3100 SymTab.ArrayLen(dt)),
|
|
|
|
|
- 3101 qr)
|
|
|
|
|
- 3102 END
|
|
|
|
|
- 3103 END;
|
|
|
|
|
- 3104 t := SymTab.IntType();
|
|
|
|
|
- 3105 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3106 END; .)
|
|
|
|
|
- 3107 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 3108 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3109 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
|
|
- 3110 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3111 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3112 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3113 t := SymTab.InvalidType;
|
|
|
|
|
- 3114 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3115 ELSE
|
|
|
|
|
- 3116 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
- 3117 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
- 3118 t := SymTab.IntType()
|
|
|
|
|
- 3119 END; .)
|
|
|
|
|
- 3120 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
- 3121 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
- 3122 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
|
|
- 3123 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3124 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3125 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
|
|
- 3126 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3127 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
|
|
- 3128 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
- 3129 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
- 3130 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3131 (* set shift/rotate: isMax
|
|
|
|
|
- 3132 doubles as "rotate" *)
|
|
|
|
|
- 3133 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3134 AND (SymTab.ClassOf(et) =
|
|
|
|
|
- 3135 SymTab.ClSet) THEN
|
|
|
|
|
- 3136 QbeGen.SetShift(q, q2,
|
|
|
|
|
- 3137 SymTab.SetWords(et),
|
|
|
|
|
- 3138 SymTab.SetCount(et), isMax,
|
|
|
|
|
- 3139 qt);
|
|
|
|
|
- 3140 t := et;
|
|
|
|
|
- 3141 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 3142 ELSE SemError(230);
|
|
|
|
|
- 3143 t := SymTab.InvalidType;
|
|
|
|
|
- 3144 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3145 END; .)
|
|
|
|
|
- 3146 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
- 3147 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
- 3148 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 3149 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3150 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3151 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
|
|
- 3152 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3153 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
|
|
- 3154 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3155 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3156 IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3157 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
- 3158 (* REAL/LONGREAL: the
|
|
|
|
|
- 3159 implementation bounds *)
|
|
|
|
|
- 3160 IF isMax THEN
|
|
|
|
|
- 3161 QbeGen.NormReal(
|
|
|
|
|
- 3162 "3.402823e38", q)
|
|
|
|
|
- 3163 ELSE QbeGen.NormReal(
|
|
|
|
|
- 3164 "-3.402823e38", q)
|
|
|
|
|
- 3165 END;
|
|
|
|
|
- 3166 t := SymTab.RealType()
|
|
|
|
|
- 3167 ELSIF (dt #
|
|
|
|
|
- 3168 SymTab.InvalidType)
|
|
|
|
|
- 3169 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3170 SymTab.ClLong) THEN
|
|
|
|
|
- 3171 IF isMax THEN
|
|
|
|
|
- 3172 QbeGen.CopyOp(
|
|
|
|
|
- 3173 "9223372036854775807", q)
|
|
|
|
|
- 3174 ELSE QbeGen.CopyOp(
|
|
|
|
|
- 3175 "-9223372036854775808", q)
|
|
|
|
|
- 3176 END;
|
|
|
|
|
- 3177 t := SymTab.LongType()
|
|
|
|
|
- 3178 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
- 3179 hi) THEN
|
|
|
|
|
- 3180 IF isMax THEN
|
|
|
|
|
- 3181 QbeGen.IntStr(hi, q)
|
|
|
|
|
- 3182 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
- 3183 END;
|
|
|
|
|
- 3184 t := SymTab.IntType()
|
|
|
|
|
- 3185 ELSE SemError(230);
|
|
|
|
|
- 3186 t := SymTab.InvalidType;
|
|
|
|
|
- 3187 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3188 END; .)
|
|
|
|
|
- 3189 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 3190 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3191 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
|
|
- 3192 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3193 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3194 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3195 t := SymTab.InvalidType;
|
|
|
|
|
- 3196 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3197 ELSE
|
|
|
|
|
- 3198 IF sfx THEN
|
|
|
|
|
- 3199 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 3200 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
- 3201 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
- 3202 QbeGen.AddrOf(qn, q)
|
|
|
|
|
- 3203 ELSE SemError(230);
|
|
|
|
|
- 3204 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3205 END;
|
|
|
|
|
- 3206 t := SymTab.AddrType()
|
|
|
|
|
- 3207 END; .)
|
|
|
|
|
- 3208 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 3209 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3210 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
|
|
- 3211 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3212 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3213 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3214 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3215 SemError(211) END;
|
|
|
|
|
- 3216 t := SymTab.CharType(); .)
|
|
|
|
|
- 3217 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
- 3218 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3219 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
|
|
- 3220 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3221 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3222 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
- 3223 IF (SymTab.ClassOf(et) #
|
|
|
|
|
- 3224 SymTab.ClChar)
|
|
|
|
|
- 3225 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3226 SymTab.ClBool)
|
|
|
|
|
- 3227 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3228 SymTab.ClEnum)
|
|
|
|
|
- 3229 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3230 SemError(211) END
|
|
|
|
|
- 3231 END;
|
|
|
|
|
- 3232 t := SymTab.IntType(); .)
|
|
|
|
|
- 3233 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
|
|
+ 3061 QbeGen.IntStr(c1, qr);
|
|
|
|
|
+ 3062 t := SymTab.IntType();
|
|
|
|
|
+ 3063 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3064 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3065 t := SymTab.InvalidType;
|
|
|
|
|
+ 3066 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3067 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 3068 SymTab.ClArray THEN
|
|
|
|
|
+ 3069 SemError(217);
|
|
|
|
|
+ 3070 t := SymTab.InvalidType;
|
|
|
|
|
+ 3071 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3072 ELSE
|
|
|
|
|
+ 3073 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 3074 t := SymTab.IntType();
|
|
|
|
|
+ 3075 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 3076 ELSE
|
|
|
|
|
+ 3077 IF isHigh THEN
|
|
|
|
|
+ 3078 QbeGen.IntStr(
|
|
|
|
|
+ 3079 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
+ 3080 ELSE
|
|
|
|
|
+ 3081 QbeGen.IntStr(VAL(
|
|
|
|
|
+ 3082 INTEGER,
|
|
|
|
|
+ 3083 SymTab.ArrayLen(dt)),
|
|
|
|
|
+ 3084 qr)
|
|
|
|
|
+ 3085 END;
|
|
|
|
|
+ 3086 t := SymTab.IntType();
|
|
|
|
|
+ 3087 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3088 END
|
|
|
|
|
+ 3089 END; .)
|
|
|
|
|
+ 3090 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3091 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3092 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
|
|
+ 3093 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3094 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3095 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3096 t := SymTab.InvalidType;
|
|
|
|
|
+ 3097 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3098 ELSE
|
|
|
|
|
+ 3099 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
+ 3100 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
+ 3101 t := SymTab.IntType()
|
|
|
|
|
+ 3102 END; .)
|
|
|
|
|
+ 3103 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
+ 3104 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
+ 3105 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
|
|
+ 3106 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3107 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3108 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
|
|
+ 3109 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3110 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
|
|
+ 3111 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
+ 3112 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
+ 3113 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3114 (* set shift/rotate: isMax
|
|
|
|
|
+ 3115 doubles as "rotate" *)
|
|
|
|
|
+ 3116 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3117 AND (SymTab.ClassOf(et) =
|
|
|
|
|
+ 3118 SymTab.ClSet) THEN
|
|
|
|
|
+ 3119 t := et;
|
|
|
|
|
+ 3120 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 3121 ELSE SemError(230);
|
|
|
|
|
+ 3122 t := SymTab.InvalidType;
|
|
|
|
|
+ 3123 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3124 END; .)
|
|
|
|
|
+ 3125 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
+ 3126 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
+ 3127 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3128 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3129 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3130 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
|
|
+ 3131 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3132 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
|
|
+ 3133 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3134 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3135 IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3136 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
+ 3137 (* REAL/LONGREAL: the
|
|
|
|
|
+ 3138 implementation bounds *)
|
|
|
|
|
+ 3139 IF isMax THEN
|
|
|
|
|
+ 3140 QbeGen.NormReal(
|
|
|
|
|
+ 3141 "3.402823e38", q)
|
|
|
|
|
+ 3142 ELSE QbeGen.NormReal(
|
|
|
|
|
+ 3143 "-3.402823e38", q)
|
|
|
|
|
+ 3144 END;
|
|
|
|
|
+ 3145 t := SymTab.RealType()
|
|
|
|
|
+ 3146 ELSIF (dt #
|
|
|
|
|
+ 3147 SymTab.InvalidType)
|
|
|
|
|
+ 3148 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 3149 SymTab.ClLong) THEN
|
|
|
|
|
+ 3150 IF isMax THEN
|
|
|
|
|
+ 3151 QbeGen.CopyOp(
|
|
|
|
|
+ 3152 "9223372036854775807", q)
|
|
|
|
|
+ 3153 ELSE QbeGen.CopyOp(
|
|
|
|
|
+ 3154 "-9223372036854775808", q)
|
|
|
|
|
+ 3155 END;
|
|
|
|
|
+ 3156 t := SymTab.LongType()
|
|
|
|
|
+ 3157 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
+ 3158 hi) THEN
|
|
|
|
|
+ 3159 IF isMax THEN
|
|
|
|
|
+ 3160 QbeGen.IntStr(hi, q)
|
|
|
|
|
+ 3161 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
+ 3162 END;
|
|
|
|
|
+ 3163 t := SymTab.IntType()
|
|
|
|
|
+ 3164 ELSE SemError(230);
|
|
|
|
|
+ 3165 t := SymTab.InvalidType;
|
|
|
|
|
+ 3166 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3167 END; .)
|
|
|
|
|
+ 3168 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3169 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3170 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
|
|
+ 3171 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3172 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3173 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3174 t := SymTab.InvalidType;
|
|
|
|
|
+ 3175 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3176 ELSE
|
|
|
|
|
+ 3177 IF sfx
|
|
|
|
|
+ 3178 OR (dk = SymTab.KindVar)
|
|
|
|
|
+ 3179 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
+ 3180 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 3181 ELSE SemError(230);
|
|
|
|
|
+ 3182 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3183 END;
|
|
|
|
|
+ 3184 t := SymTab.AddrType()
|
|
|
|
|
+ 3185 END; .)
|
|
|
|
|
+ 3186 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3187 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3188 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
|
|
+ 3189 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3190 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3191 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3192 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3193 SemError(211) END;
|
|
|
|
|
+ 3194 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3195 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
+ 3196 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3197 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
|
|
+ 3198 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3199 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3200 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
+ 3201 IF (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3202 SymTab.ClChar)
|
|
|
|
|
+ 3203 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3204 SymTab.ClBool)
|
|
|
|
|
+ 3205 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3206 SymTab.ClEnum)
|
|
|
|
|
+ 3207 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3208 SemError(211) END
|
|
|
|
|
+ 3209 END;
|
|
|
|
|
+ 3210 t := SymTab.IntType(); .)
|
|
|
|
|
+ 3211 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3212 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3213 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
|
|
+ 3214 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3215 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3216 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
+ 3217 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3218 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3219 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3220 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3221 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
|
|
+ 3222 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3223 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3224 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
+ 3225 CHAR -> UCHAR (identity);
|
|
|
|
|
+ 3226 INTEGER familly -> UCHAR
|
|
|
|
|
+ 3227 (codepoint value). *)
|
|
|
|
|
+ 3228 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3229 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
+ 3230 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3231 SemError(211) END;
|
|
|
|
|
+ 3232 t := SymTab.UCharType(); .)
|
|
|
|
|
+ 3233 | "CHR8" "(" Expr<et, q> ")"
|
|
|
3234 (. astNode := AST.MakeNode(AST.NkCall);
|
|
3234 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3235 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
|
|
|
|
+ 3235 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
3236 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
3236 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
3237 astCur := astNode; astIsLit := TRUE; .)
|
|
3237 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3238 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
- 3239 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3240 t := SymTab.CharType(); .)
|
|
|
|
|
- 3241 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 3242 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3243 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
|
|
- 3244 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3245 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3246 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
- 3247 CHAR -> UCHAR (identity);
|
|
|
|
|
- 3248 INTEGER familly -> UCHAR
|
|
|
|
|
- 3249 (codepoint value). *)
|
|
|
|
|
|
|
+ 3238 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3239 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3240 SemError(211) END;
|
|
|
|
|
+ 3241 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3242 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3243 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3244 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
|
|
+ 3245 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3246 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3247 (. (* UORD(u): the codepoint as a
|
|
|
|
|
+ 3248 32-bit ordinal (INTEGER),
|
|
|
|
|
+ 3249 cf. ORD for CHAR. *)
|
|
|
3250 IF (et # SymTab.InvalidType)
|
|
3250 IF (et # SymTab.InvalidType)
|
|
|
- 3251 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
- 3252 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3253 SemError(211) END;
|
|
|
|
|
- 3254 t := SymTab.UCharType(); .)
|
|
|
|
|
- 3255 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
- 3256 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3257 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
|
|
- 3258 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3259 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3260 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3261 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 3262 SemError(211) END;
|
|
|
|
|
- 3263 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 3264 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
- 3265 t := SymTab.CharType(); .)
|
|
|
|
|
- 3266 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
- 3267 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3268 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
|
|
- 3269 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3270 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3271 (. (* UORD(u): the codepoint as a
|
|
|
|
|
- 3272 32-bit ordinal (INTEGER),
|
|
|
|
|
- 3273 cf. ORD for CHAR. *)
|
|
|
|
|
- 3274 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3275 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 3276 SemError(211) END;
|
|
|
|
|
- 3277 t := SymTab.IntType(); .)
|
|
|
|
|
- 3278 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
- 3279 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3280 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
|
|
- 3281 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3282 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3283 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3284 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
- 3285 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3286 SymTab.ClReal) THEN
|
|
|
|
|
- 3287 SemError(211)
|
|
|
|
|
- 3288 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
- 3289 SymTab.ClassOf(et) =
|
|
|
|
|
- 3290 SymTab.ClReal);
|
|
|
|
|
- 3291 QbeGen.CopyOp(qa, q)
|
|
|
|
|
- 3292 END;
|
|
|
|
|
- 3293 t := et; .)
|
|
|
|
|
- 3294 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
|
|
- 3295 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3296 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
|
|
- 3297 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
- 3298 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
- 3299 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3300 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
- 3301 SemError(201);
|
|
|
|
|
- 3302 t := SymTab.InvalidType
|
|
|
|
|
- 3303 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
- 3304 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3305 t := SymTab.InvalidType
|
|
|
|
|
- 3306 ELSIF et =
|
|
|
|
|
- 3307 SymTab.InvalidType THEN
|
|
|
|
|
- 3308 t := vt
|
|
|
|
|
- 3309 ELSE
|
|
|
|
|
- 3310 c1 := SymTab.ClassOf(et);
|
|
|
|
|
- 3311 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
- 3312 IF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3313 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3314 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 3315 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3316 t := vt
|
|
|
|
|
- 3317 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3318 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3319 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
- 3320 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3321 t := vt
|
|
|
|
|
- 3322 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3323 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3324 QbeGen.ConvIR(q, qa);
|
|
|
|
|
- 3325 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3326 t := vt
|
|
|
|
|
- 3327 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3328 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3329 QbeGen.ConvLR(q, qa);
|
|
|
|
|
- 3330 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3331 t := vt
|
|
|
|
|
- 3332 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3333 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3334 QbeGen.ConvRI(q, qa);
|
|
|
|
|
- 3335 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3336 t := vt
|
|
|
|
|
- 3337 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3338 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3339 QbeGen.ConvRL(q, qa);
|
|
|
|
|
- 3340 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3341 t := vt
|
|
|
|
|
- 3342 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
- 3343 OR (c1 =
|
|
|
|
|
- 3344 SymTab.ClChar)
|
|
|
|
|
- 3345 OR (c1 =
|
|
|
|
|
- 3346 SymTab.ClBool)
|
|
|
|
|
- 3347 OR (c1 =
|
|
|
|
|
- 3348 SymTab.ClEnum))
|
|
|
|
|
- 3349 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
- 3350 OR (c2 =
|
|
|
|
|
- 3351 SymTab.ClChar)
|
|
|
|
|
- 3352 OR (c2 =
|
|
|
|
|
- 3353 SymTab.ClBool)
|
|
|
|
|
- 3354 OR (c2 =
|
|
|
|
|
- 3355 SymTab.ClEnum)) THEN
|
|
|
|
|
- 3356 t := vt
|
|
|
|
|
- 3357 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
- 3358 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
- 3359 t := vt
|
|
|
|
|
- 3360 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3361 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3362 t := vt
|
|
|
|
|
- 3363 ELSE SemError(230);
|
|
|
|
|
- 3364 t := SymTab.InvalidType
|
|
|
|
|
- 3365 END
|
|
|
|
|
- 3366 END
|
|
|
|
|
- 3367 END; .)
|
|
|
|
|
- 3368 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
- 3369 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
|
|
- 3370 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
- 3371 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
|
|
- 3372 IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 3373 t := SymTab.BoolType()
|
|
|
|
|
- 3374 ELSE SemError(212);
|
|
|
|
|
- 3375 t := SymTab.InvalidType END;
|
|
|
|
|
- 3376 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 3377 QbeGen.NotQ(q2, q)
|
|
|
|
|
- 3378 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3379 END;
|
|
|
|
|
- 3380 astIsLit := TRUE;
|
|
|
|
|
- 3381 astCur := AST.MakeUn(
|
|
|
|
|
- 3382 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
|
|
- 3383 )
|
|
|
|
|
- 3384 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
- 3385 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
- 3386 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
- 3387 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
- 3388 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3389 (. VAR astNode: AST.Node; .)
|
|
|
|
|
- 3390 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
- 3391 SymTab.NewSubR(0, 255));
|
|
|
|
|
- 3392 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
|
|
- 3393 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
- 3394 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
- 3395 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
|
|
- 3396 "}" (. astCur := astNode; .) .
|
|
|
|
|
- 3397 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
- 3398 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
- 3399 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
- 3400 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3401 (. VAR nw: CARDINAL;
|
|
|
|
|
- 3402 astNode, astTail: AST.Node;
|
|
|
|
|
- 3403 savedCls: INTEGER; .)
|
|
|
|
|
- 3404 = "{" (. savedCls := braceCls;
|
|
|
|
|
- 3405 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
|
|
- 3406 AST.SetTy(astNode, vt);
|
|
|
|
|
- 3407 astTail := astNode;
|
|
|
|
|
- 3408 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3409 braceCls := -1
|
|
|
|
|
- 3410 ELSE braceCls :=
|
|
|
|
|
- 3411 SymTab.ClassOf(vt)
|
|
|
|
|
- 3412 END;
|
|
|
|
|
- 3413 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3414 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3415 nw := 8
|
|
|
|
|
- 3416 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
- 3417 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
- 3418 END;
|
|
|
|
|
- 3419 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
- 3420 QbeGen.SetZero(q, nw)
|
|
|
|
|
- 3421 ELSIF (braceCls =
|
|
|
|
|
- 3422 SymTab.ClArray)
|
|
|
|
|
- 3423 OR (braceCls =
|
|
|
|
|
- 3424 SymTab.ClRecord)
|
|
|
|
|
- 3425 OR (braceCls =
|
|
|
|
|
- 3426 SymTab.ClClass) THEN
|
|
|
|
|
- 3427 QbeGen.CtorBegin(vt)
|
|
|
|
|
- 3428 ELSE
|
|
|
|
|
- 3429 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
- 3430 SemError(230) END;
|
|
|
|
|
- 3431 braceCls := -1
|
|
|
|
|
- 3432 END; .)
|
|
|
|
|
- 3433 [ BraceElem<vt, q, astNode, astTail>
|
|
|
|
|
- 3434 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
|
|
- 3435 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3436 OR (braceCls =
|
|
|
|
|
- 3437 SymTab.ClRecord)
|
|
|
|
|
- 3438 OR (braceCls =
|
|
|
|
|
- 3439 SymTab.ClClass) THEN
|
|
|
|
|
- 3440 QbeGen.CtorEnd(q)
|
|
|
|
|
- 3441 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
- 3442 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3443 END;
|
|
|
|
|
- 3444 braceCls := savedCls; .)
|
|
|
|
|
- 3445 (. astCur := astNode; .) .
|
|
|
|
|
- 3446 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
|
|
- 3447 VAR node, tail: AST.Node>
|
|
|
|
|
- 3448 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3449 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3450 v, v2, reps, k: INTEGER;
|
|
|
|
|
- 3451 elem: SymTab.TypeIndex;
|
|
|
|
|
- 3452 lo: INTEGER;
|
|
|
|
|
- 3453 span: CARDINAL;
|
|
|
|
|
- 3454 cl, cl2: INTEGER;
|
|
|
|
|
- 3455 hasR, hasB: BOOLEAN;
|
|
|
|
|
- 3456 astEl: AST.Node; .)
|
|
|
|
|
- 3457 = (. hasR := FALSE; hasB := FALSE;
|
|
|
|
|
- 3458 reps := 1; .)
|
|
|
|
|
- 3459 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
- 3460 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
- 3461 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
- 3462 hasR := TRUE; .) ]
|
|
|
|
|
- 3463 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
- 3464 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3465 IF hasB THEN SemError(230) END;
|
|
|
|
|
- 3466 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
- 3467 span := SymTab.SetCount(vt);
|
|
|
|
|
- 3468 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3469 OR (hasR AND (et2 =
|
|
|
|
|
- 3470 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3471 ELSE cl :=
|
|
|
|
|
- 3472 SymTab.ClassOf(et);
|
|
|
|
|
- 3473 IF hasR THEN
|
|
|
|
|
- 3474 cl2 :=
|
|
|
|
|
- 3475 SymTab.ClassOf(et2)
|
|
|
|
|
- 3476 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3477 END;
|
|
|
|
|
- 3478 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3479 OR (hasR AND NOT
|
|
|
|
|
- 3480 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3481 THEN
|
|
|
|
|
- 3482 SemError(222)
|
|
|
|
|
- 3483 ELSIF hasR
|
|
|
|
|
- 3484 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3485 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3486 v2)
|
|
|
|
|
- 3487 AND ((v < lo)
|
|
|
|
|
- 3488 OR (v2 < lo)
|
|
|
|
|
- 3489 OR (v >= lo +
|
|
|
|
|
- 3490 VAL(INTEGER, span))
|
|
|
|
|
- 3491 OR (v2 >= lo +
|
|
|
|
|
- 3492 VAL(INTEGER, span))
|
|
|
|
|
- 3493 OR (v > v2)) THEN
|
|
|
|
|
- 3494 SemError(222)
|
|
|
|
|
- 3495 ELSIF hasR THEN
|
|
|
|
|
- 3496 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3497 lo, span)
|
|
|
|
|
- 3498 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3499 v)
|
|
|
|
|
- 3500 AND ((v < lo)
|
|
|
|
|
- 3501 OR (v >= lo +
|
|
|
|
|
- 3502 VAL(INTEGER,
|
|
|
|
|
- 3503 span))) THEN
|
|
|
|
|
- 3504 SemError(222)
|
|
|
|
|
- 3505 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3506 lo, span)
|
|
|
|
|
- 3507 END
|
|
|
|
|
- 3508 END
|
|
|
|
|
- 3509 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3510 OR (braceCls =
|
|
|
|
|
- 3511 SymTab.ClRecord)
|
|
|
|
|
- 3512 OR (braceCls =
|
|
|
|
|
- 3513 SymTab.ClClass) THEN
|
|
|
|
|
- 3514 IF hasR THEN SemError(230) END;
|
|
|
|
|
- 3515 reps := 1;
|
|
|
|
|
- 3516 IF hasB THEN
|
|
|
|
|
- 3517 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
- 3518 AND (v2 >= 1) THEN
|
|
|
|
|
- 3519 reps := v2
|
|
|
|
|
- 3520 ELSE SemError(230)
|
|
|
|
|
- 3521 END
|
|
|
|
|
- 3522 END;
|
|
|
|
|
- 3523 k := 0;
|
|
|
|
|
- 3524 WHILE k < reps DO
|
|
|
|
|
- 3525 QbeGen.CtorElem(qe);
|
|
|
|
|
- 3526 INC(k)
|
|
|
|
|
- 3527 END
|
|
|
|
|
- 3528 END; .)
|
|
|
|
|
- 3529 (. (* the BY form repeats the
|
|
|
|
|
- 3530 element; keep the AST in
|
|
|
|
|
- 3531 step with CtorElem *)
|
|
|
|
|
- 3532 k := 0;
|
|
|
|
|
- 3533 WHILE k < reps DO
|
|
|
|
|
- 3534 AstAppend(AST.NkBlock,
|
|
|
|
|
- 3535 node, tail, astEl);
|
|
|
|
|
- 3536 INC(k)
|
|
|
|
|
- 3537 END; .) .
|
|
|
|
|
- 3538 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3539 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3540 v, v2: INTEGER;
|
|
|
|
|
- 3541 lo: INTEGER;
|
|
|
|
|
- 3542 span: CARDINAL;
|
|
|
|
|
- 3543 cl, cl2: INTEGER;
|
|
|
|
|
- 3544 hasR: BOOLEAN;
|
|
|
|
|
- 3545 astEl: AST.Node; .)
|
|
|
|
|
- 3546 = (. hasR := FALSE; .)
|
|
|
|
|
- 3547 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
- 3548 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
- 3549 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
- 3550 hasR := TRUE; .) ]
|
|
|
|
|
- 3551 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
- 3552 span := SymTab.SetCount(st);
|
|
|
|
|
- 3553 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3554 OR (hasR AND (et2 =
|
|
|
|
|
- 3555 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3556 ELSE cl :=
|
|
|
|
|
- 3557 SymTab.ClassOf(et);
|
|
|
|
|
- 3558 IF hasR THEN
|
|
|
|
|
- 3559 cl2 :=
|
|
|
|
|
- 3560 SymTab.ClassOf(et2)
|
|
|
|
|
- 3561 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3562 END;
|
|
|
|
|
- 3563 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3564 OR (hasR AND NOT
|
|
|
|
|
- 3565 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3566 THEN
|
|
|
|
|
- 3567 SemError(222)
|
|
|
|
|
- 3568 ELSIF hasR
|
|
|
|
|
- 3569 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3570 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3571 v2)
|
|
|
|
|
- 3572 AND ((v < lo)
|
|
|
|
|
- 3573 OR (v2 < lo)
|
|
|
|
|
- 3574 OR (v >= lo +
|
|
|
|
|
- 3575 VAL(INTEGER, span))
|
|
|
|
|
- 3576 OR (v2 >= lo +
|
|
|
|
|
- 3577 VAL(INTEGER, span))
|
|
|
|
|
- 3578 OR (v > v2)) THEN
|
|
|
|
|
- 3579 SemError(222)
|
|
|
|
|
- 3580 ELSIF hasR THEN
|
|
|
|
|
- 3581 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3582 lo, span)
|
|
|
|
|
- 3583 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3584 v)
|
|
|
|
|
- 3585 AND ((v < lo)
|
|
|
|
|
- 3586 OR (v >= lo +
|
|
|
|
|
- 3587 VAL(INTEGER,
|
|
|
|
|
- 3588 span))) THEN
|
|
|
|
|
- 3589 SemError(222)
|
|
|
|
|
- 3590 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3591 lo, span)
|
|
|
|
|
- 3592 END
|
|
|
|
|
- 3593 END; .)
|
|
|
|
|
- 3594 (. AST.SetChild(node,
|
|
|
|
|
- 3595 AST.NChild(node), astEl); .) .
|
|
|
|
|
- 3596 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
- 3597 = ident (. LexName(n); .) .
|
|
|
|
|
- 3598
|
|
|
|
|
- 3599 END M2.
|
|
|
|
|
|
|
+ 3251 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3252 SemError(211) END;
|
|
|
|
|
+ 3253 t := SymTab.IntType(); .)
|
|
|
|
|
+ 3254 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3255 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3256 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
|
|
+ 3257 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3258 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3259 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3260 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
+ 3261 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3262 SymTab.ClReal) THEN
|
|
|
|
|
+ 3263 SemError(211)
|
|
|
|
|
+ 3264 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
+ 3265 SymTab.ClassOf(et) =
|
|
|
|
|
+ 3266 SymTab.ClReal);
|
|
|
|
|
+ 3267 QbeGen.CopyOp(qa, q)
|
|
|
|
|
+ 3268 END;
|
|
|
|
|
+ 3269 t := et; .)
|
|
|
|
|
+ 3270 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
|
|
+ 3271 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3272 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
|
|
+ 3273 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
+ 3274 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
+ 3275 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3276 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
+ 3277 SemError(201);
|
|
|
|
|
+ 3278 t := SymTab.InvalidType
|
|
|
|
|
+ 3279 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
+ 3280 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3281 t := SymTab.InvalidType
|
|
|
|
|
+ 3282 ELSIF et =
|
|
|
|
|
+ 3283 SymTab.InvalidType THEN
|
|
|
|
|
+ 3284 t := vt
|
|
|
|
|
+ 3285 ELSE
|
|
|
|
|
+ 3286 c1 := SymTab.ClassOf(et);
|
|
|
|
|
+ 3287 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
+ 3288 IF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3289 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3290 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 3291 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3292 t := vt
|
|
|
|
|
+ 3293 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3294 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3295 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
+ 3296 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3297 t := vt
|
|
|
|
|
+ 3298 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3299 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3300 QbeGen.ConvIR(q, qa);
|
|
|
|
|
+ 3301 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3302 t := vt
|
|
|
|
|
+ 3303 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3304 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3305 QbeGen.ConvLR(q, qa);
|
|
|
|
|
+ 3306 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3307 t := vt
|
|
|
|
|
+ 3308 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3309 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3310 QbeGen.ConvRI(q, qa);
|
|
|
|
|
+ 3311 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3312 t := vt
|
|
|
|
|
+ 3313 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3314 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3315 QbeGen.ConvRL(q, qa);
|
|
|
|
|
+ 3316 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3317 t := vt
|
|
|
|
|
+ 3318 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
+ 3319 OR (c1 =
|
|
|
|
|
+ 3320 SymTab.ClChar)
|
|
|
|
|
+ 3321 OR (c1 =
|
|
|
|
|
+ 3322 SymTab.ClBool)
|
|
|
|
|
+ 3323 OR (c1 =
|
|
|
|
|
+ 3324 SymTab.ClEnum))
|
|
|
|
|
+ 3325 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
+ 3326 OR (c2 =
|
|
|
|
|
+ 3327 SymTab.ClChar)
|
|
|
|
|
+ 3328 OR (c2 =
|
|
|
|
|
+ 3329 SymTab.ClBool)
|
|
|
|
|
+ 3330 OR (c2 =
|
|
|
|
|
+ 3331 SymTab.ClEnum)) THEN
|
|
|
|
|
+ 3332 t := vt
|
|
|
|
|
+ 3333 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
+ 3334 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
+ 3335 t := vt
|
|
|
|
|
+ 3336 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3337 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3338 t := vt
|
|
|
|
|
+ 3339 ELSE SemError(230);
|
|
|
|
|
+ 3340 t := SymTab.InvalidType
|
|
|
|
|
+ 3341 END
|
|
|
|
|
+ 3342 END
|
|
|
|
|
+ 3343 END; .)
|
|
|
|
|
+ 3344 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
+ 3345 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
|
|
+ 3346 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
+ 3347 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
|
|
+ 3348 IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 3349 t := SymTab.BoolType()
|
|
|
|
|
+ 3350 ELSE SemError(212);
|
|
|
|
|
+ 3351 t := SymTab.InvalidType END;
|
|
|
|
|
+ 3352 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 3353 QbeGen.NotQ(q2, q)
|
|
|
|
|
+ 3354 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3355 END;
|
|
|
|
|
+ 3356 astIsLit := TRUE;
|
|
|
|
|
+ 3357 astCur := AST.MakeUn(
|
|
|
|
|
+ 3358 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
|
|
+ 3359 )
|
|
|
|
|
+ 3360 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
+ 3361 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
+ 3362 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
+ 3363 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
+ 3364 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3365 (. VAR astNode: AST.Node; .)
|
|
|
|
|
+ 3366 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
+ 3367 SymTab.NewSubR(0, 255));
|
|
|
|
|
+ 3368 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
|
|
+ 3369 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
+ 3370 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
+ 3371 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
|
|
+ 3372 "}" (. astCur := astNode; .) .
|
|
|
|
|
+ 3373 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
+ 3374 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
+ 3375 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
+ 3376 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3377 (. VAR nw: CARDINAL;
|
|
|
|
|
+ 3378 astNode, astTail: AST.Node;
|
|
|
|
|
+ 3379 savedCls: INTEGER; .)
|
|
|
|
|
+ 3380 = "{" (. savedCls := braceCls;
|
|
|
|
|
+ 3381 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
|
|
+ 3382 AST.SetTy(astNode, vt);
|
|
|
|
|
+ 3383 astTail := astNode;
|
|
|
|
|
+ 3384 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3385 braceCls := -1
|
|
|
|
|
+ 3386 ELSE braceCls :=
|
|
|
|
|
+ 3387 SymTab.ClassOf(vt)
|
|
|
|
|
+ 3388 END;
|
|
|
|
|
+ 3389 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3390 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3391 nw := 8
|
|
|
|
|
+ 3392 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
+ 3393 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
+ 3394 END;
|
|
|
|
|
+ 3395 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
+ 3396 QbeGen.SetZero(q, nw)
|
|
|
|
|
+ 3397 ELSIF (braceCls =
|
|
|
|
|
+ 3398 SymTab.ClArray)
|
|
|
|
|
+ 3399 OR (braceCls =
|
|
|
|
|
+ 3400 SymTab.ClRecord)
|
|
|
|
|
+ 3401 OR (braceCls =
|
|
|
|
|
+ 3402 SymTab.ClClass) THEN
|
|
|
|
|
+ 3403 QbeGen.CtorBegin(vt)
|
|
|
|
|
+ 3404 ELSE
|
|
|
|
|
+ 3405 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
+ 3406 SemError(230) END;
|
|
|
|
|
+ 3407 braceCls := -1
|
|
|
|
|
+ 3408 END; .)
|
|
|
|
|
+ 3409 [ BraceElem<vt, q, astNode, astTail>
|
|
|
|
|
+ 3410 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
|
|
+ 3411 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3412 OR (braceCls =
|
|
|
|
|
+ 3413 SymTab.ClRecord)
|
|
|
|
|
+ 3414 OR (braceCls =
|
|
|
|
|
+ 3415 SymTab.ClClass) THEN
|
|
|
|
|
+ 3416 QbeGen.CtorEnd(q)
|
|
|
|
|
+ 3417 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
+ 3418 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3419 END;
|
|
|
|
|
+ 3420 braceCls := savedCls; .)
|
|
|
|
|
+ 3421 (. astCur := astNode; .) .
|
|
|
|
|
+ 3422 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
|
|
+ 3423 VAR node, tail: AST.Node>
|
|
|
|
|
+ 3424 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3425 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3426 v, v2, reps, k: INTEGER;
|
|
|
|
|
+ 3427 elem: SymTab.TypeIndex;
|
|
|
|
|
+ 3428 lo: INTEGER;
|
|
|
|
|
+ 3429 span: CARDINAL;
|
|
|
|
|
+ 3430 cl, cl2: INTEGER;
|
|
|
|
|
+ 3431 hasR, hasB: BOOLEAN;
|
|
|
|
|
+ 3432 astEl: AST.Node; .)
|
|
|
|
|
+ 3433 = (. hasR := FALSE; hasB := FALSE;
|
|
|
|
|
+ 3434 reps := 1; .)
|
|
|
|
|
+ 3435 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
+ 3436 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
+ 3437 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
+ 3438 hasR := TRUE; .) ]
|
|
|
|
|
+ 3439 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
+ 3440 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3441 IF hasB THEN SemError(230) END;
|
|
|
|
|
+ 3442 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
+ 3443 span := SymTab.SetCount(vt);
|
|
|
|
|
+ 3444 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3445 OR (hasR AND (et2 =
|
|
|
|
|
+ 3446 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3447 ELSE cl :=
|
|
|
|
|
+ 3448 SymTab.ClassOf(et);
|
|
|
|
|
+ 3449 IF hasR THEN
|
|
|
|
|
+ 3450 cl2 :=
|
|
|
|
|
+ 3451 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3452 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3453 END;
|
|
|
|
|
+ 3454 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3455 OR (hasR AND NOT
|
|
|
|
|
+ 3456 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3457 THEN
|
|
|
|
|
+ 3458 SemError(222)
|
|
|
|
|
+ 3459 ELSIF hasR
|
|
|
|
|
+ 3460 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3461 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3462 v2)
|
|
|
|
|
+ 3463 AND ((v < lo)
|
|
|
|
|
+ 3464 OR (v2 < lo)
|
|
|
|
|
+ 3465 OR (v >= lo +
|
|
|
|
|
+ 3466 VAL(INTEGER, span))
|
|
|
|
|
+ 3467 OR (v2 >= lo +
|
|
|
|
|
+ 3468 VAL(INTEGER, span))
|
|
|
|
|
+ 3469 OR (v > v2)) THEN
|
|
|
|
|
+ 3470 SemError(222)
|
|
|
|
|
+ 3471 ELSIF hasR THEN
|
|
|
|
|
+ 3472 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3473 lo, span)
|
|
|
|
|
+ 3474 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3475 v)
|
|
|
|
|
+ 3476 AND ((v < lo)
|
|
|
|
|
+ 3477 OR (v >= lo +
|
|
|
|
|
+ 3478 VAL(INTEGER,
|
|
|
|
|
+ 3479 span))) THEN
|
|
|
|
|
+ 3480 SemError(222)
|
|
|
|
|
+ 3481 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3482 lo, span)
|
|
|
|
|
+ 3483 END
|
|
|
|
|
+ 3484 END
|
|
|
|
|
+ 3485 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3486 OR (braceCls =
|
|
|
|
|
+ 3487 SymTab.ClRecord)
|
|
|
|
|
+ 3488 OR (braceCls =
|
|
|
|
|
+ 3489 SymTab.ClClass) THEN
|
|
|
|
|
+ 3490 IF hasR THEN SemError(230) END;
|
|
|
|
|
+ 3491 reps := 1;
|
|
|
|
|
+ 3492 IF hasB THEN
|
|
|
|
|
+ 3493 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
+ 3494 AND (v2 >= 1) THEN
|
|
|
|
|
+ 3495 reps := v2
|
|
|
|
|
+ 3496 ELSE SemError(230)
|
|
|
|
|
+ 3497 END
|
|
|
|
|
+ 3498 END;
|
|
|
|
|
+ 3499 k := 0;
|
|
|
|
|
+ 3500 WHILE k < reps DO
|
|
|
|
|
+ 3501 QbeGen.CtorElem(qe);
|
|
|
|
|
+ 3502 INC(k)
|
|
|
|
|
+ 3503 END
|
|
|
|
|
+ 3504 END; .)
|
|
|
|
|
+ 3505 (. (* the BY form repeats the
|
|
|
|
|
+ 3506 element; keep the AST in
|
|
|
|
|
+ 3507 step with CtorElem *)
|
|
|
|
|
+ 3508 k := 0;
|
|
|
|
|
+ 3509 WHILE k < reps DO
|
|
|
|
|
+ 3510 AstAppend(AST.NkBlock,
|
|
|
|
|
+ 3511 node, tail, astEl);
|
|
|
|
|
+ 3512 INC(k)
|
|
|
|
|
+ 3513 END; .) .
|
|
|
|
|
+ 3514 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3515 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3516 v, v2: INTEGER;
|
|
|
|
|
+ 3517 lo: INTEGER;
|
|
|
|
|
+ 3518 span: CARDINAL;
|
|
|
|
|
+ 3519 cl, cl2: INTEGER;
|
|
|
|
|
+ 3520 hasR: BOOLEAN;
|
|
|
|
|
+ 3521 astEl: AST.Node; .)
|
|
|
|
|
+ 3522 = (. hasR := FALSE; .)
|
|
|
|
|
+ 3523 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
+ 3524 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
+ 3525 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
+ 3526 hasR := TRUE; .) ]
|
|
|
|
|
+ 3527 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
+ 3528 span := SymTab.SetCount(st);
|
|
|
|
|
+ 3529 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3530 OR (hasR AND (et2 =
|
|
|
|
|
+ 3531 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3532 ELSE cl :=
|
|
|
|
|
+ 3533 SymTab.ClassOf(et);
|
|
|
|
|
+ 3534 IF hasR THEN
|
|
|
|
|
+ 3535 cl2 :=
|
|
|
|
|
+ 3536 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3537 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3538 END;
|
|
|
|
|
+ 3539 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3540 OR (hasR AND NOT
|
|
|
|
|
+ 3541 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3542 THEN
|
|
|
|
|
+ 3543 SemError(222)
|
|
|
|
|
+ 3544 ELSIF hasR
|
|
|
|
|
+ 3545 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3546 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3547 v2)
|
|
|
|
|
+ 3548 AND ((v < lo)
|
|
|
|
|
+ 3549 OR (v2 < lo)
|
|
|
|
|
+ 3550 OR (v >= lo +
|
|
|
|
|
+ 3551 VAL(INTEGER, span))
|
|
|
|
|
+ 3552 OR (v2 >= lo +
|
|
|
|
|
+ 3553 VAL(INTEGER, span))
|
|
|
|
|
+ 3554 OR (v > v2)) THEN
|
|
|
|
|
+ 3555 SemError(222)
|
|
|
|
|
+ 3556 ELSIF hasR THEN
|
|
|
|
|
+ 3557 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3558 lo, span)
|
|
|
|
|
+ 3559 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3560 v)
|
|
|
|
|
+ 3561 AND ((v < lo)
|
|
|
|
|
+ 3562 OR (v >= lo +
|
|
|
|
|
+ 3563 VAL(INTEGER,
|
|
|
|
|
+ 3564 span))) THEN
|
|
|
|
|
+ 3565 SemError(222)
|
|
|
|
|
+ 3566 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3567 lo, span)
|
|
|
|
|
+ 3568 END
|
|
|
|
|
+ 3569 END; .)
|
|
|
|
|
+ 3570 (. AST.SetChild(node,
|
|
|
|
|
+ 3571 AST.NChild(node), astEl); .) .
|
|
|
|
|
+ 3572 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
+ 3573 = ident (. LexName(n); .) .
|
|
|
|
|
+ 3574
|
|
|
|
|
+ 3575 END M2.
|
|
|
|
|
|
|
|
0 errors
|
|
0 errors
|
|
|
|
|
|