Parsing... BEGIN INT tk_COLON = ABS : ; INT tk_LESS = ABS < ; INT tk_GREATER = ABS > ; INT tk_DIV = ABS / ; INT tk_EQUAL = ABS = ; INT tk_MULT = ABS * ; INT tk_PLUS = ABS + ; INT tk_MINUS = ABS - ; INT tk_PIPE = ABS | ; INT tk_LBRACKET = ABS [ ; INT tk_RBRACKET = ABS ] ; INT tk_LPARENTH = ABS ( ; INT tk_RPARENTH = ABS ) ; INT tk_SEMICOLON = ABS ; ; INT tk_COMMA = ABS , ; INT tk_REF = 257 ; INT tk_LOC = 258 ; INT tk_STRUCT = 259 ; INT tk_UNION = 260 ; INT tk_TRUE = 261 ; INT tk_FALSE = 262 ; INT tk_NIL = 263 ; INT tk_CHARCONST = 264 ; INT tk_POWER = 265 ; INT tk_UPB = 266 ; INT tk_LWB = 267 ; INT tk_BEGIN = 268 ; INT tk_END = 269 ; INT tk_IF = 270 ; INT tk_THEN = 271 ; INT tk_ELSE = 272 ; INT tk_ELIF = 273 ; INT tk_FI = 274 ; INT tk_FOR = 275 ; INT tk_FROM = 276 ; INT tk_BY = 277 ; INT tk_TO = 278 ; INT tk_WHILE = 279 ; INT tk_DO = 280 ; INT tk_OD = 281 ; INT tk_REPR = 282 ; INT tk_FORWARD = 283 ; INT tk_MOD = 284 ; INT tk_ESAC = 285 ; INT tk_PROC = 286 ; INT tk_ID = 287 ; INT tk_INTCONST = 288 ; INT tk_STRCONST = 289 ; INT tk_COMMENT = 290 ; INT tk_MODE = 291 ; INT tk_AMODE = 292 ; INT tk_ASSIGN = 293 ; INT tk_OR = 294 ; INT tk_OR = 295 ; INT tk_AND = 296 ; INT tk_AND = 297 ; INT tk_NOT = 298 ; INT tk_ABS = 299 ; INT tk_NEQ = 300 ; INT tk_GEQ = 301 ; INT tk_LEQ = 302 ; INT tk_IS = 303 ; INT tk_ISNT = 304 ; INT tk_OF = 305 ; INT tk_EOF = 0 ; INT tk_ERROR = 1001 ; FORWARD PROC debugger = VOID ; INT string_size = 256 ; INT array_header_size = 8 ; INT struc_header_size = 0 ; MODE TOKEN = STRUCT ( INT id , STRING str , STRING descr , INT line , BOOL used ) ; TOKEN token ; CHAR nextChar := REPR 0 ; INT line := 1 ; BOOL debug_echo := FALSE ; BOOL debug_stop := FALSE ; BOOL debug_stepwise := FALSE ; BOOL debug_expr := FALSE ; BOOL code_refs := FALSE ; BOOL code_comments := FALSE ; PROC error = Stack frame produced ( STRING msg ) VOID : BEGIN printf ( "ERROR: at token '%s', %s(%i): %s\n" , str OF token , descr OF token , id OF token , msg ) ; close ( 1 ) ; close ( 5 ) ; exit ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25: * other instruction error 25: ; PROC read = Stack frame produced CHAR : BEGIN CHAR ch := readc ( 1 ) ; ch END Generating code... Stack frame produced 10:11:12:13:14: * other instruction read 14: ; PROC itos = Stack frame produced ( INT value , REF STRING s ) VOID : BEGIN INT val := value ; INT d , i ; INT base ; BOOL started := FALSE ; base := 1000000 ; IF val < 0 THEN s [ 0 ] := - ; val := - val ; i := 1 ; ELSE i := 0 ; FI ; WHILE base > 1 DO d := ABS 0 ; WHILE val >= base DO d := d + 1 ; val := val - base ; OD ; IF started OR d > ABS 0 THEN s [ i ] := REPR d ; started := TRUE ; i := i + 1 ; FI ; base := base / 10 ; OD ; s [ i ] := REPR ( val + ABS 0 ) ; s [ i + 1 ] := REPR 0 ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60: * other instruction itos 60: ; PROC IsDigit = Stack frame produced ( STRING s ) BOOL : BEGIN s [ 0 ] = - OR ( s [ 0 ] >= 0 AND s [ 0 ] <= 9 ) END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20: * other instruction IsDigit 20: ; PROC StrEqual = Stack frame produced ( STRING s1 , STRING s2 ) BOOL : BEGIN INT i := 0 ; WHILE i < string_size AND s1 [ i ] /= REPR 0 AND s2 [ i ] /= REPR 0 AND s1 [ i ] = s2 [ i ] DO i := i + 1 OD ; s1 [ i ] = s2 [ i ] END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35: * other instruction StrEqual 35: ; PROC StrLen = Stack frame produced ( STRING s ) INT : BEGIN INT i := 0 ; WHILE ( s [ i ] /= REPR 0 ) DO i := i + 1 OD ; i END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22: * other instruction StrLen 22: ; PROC StrUCase = Stack frame produced ( STRING s ) BOOL : BEGIN INT i := 0 ; WHILE i < string_size AND s [ i ] /= REPR 0 AND s [ i ] >= A AND s [ i ] <= Z DO i := i + 1 OD ; s [ i ] = REPR 0 END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33: * other instruction StrUCase 33: ; PROC StrFind = Stack frame produced ( STRING s , CHAR ch , INT start ) INT : BEGIN INT i := start ; WHILE i < string_size AND s [ i ] /= REPR 0 AND s [ i ] /= ch DO i := i + 1 ; OD ; i END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27: * other instruction StrFind 27: ; PROC StrBelongs = Stack frame produced ( STRING s , CHAR ch ) BOOL : BEGIN INT i := 0 ; WHILE i < string_size AND s [ i ] /= REPR 0 AND s [ i ] /= ch DO i := i + 1 ; OD ; s [ i ] /= REPR 0 END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30: * other instruction StrBelongs 30: ; PROC StrAssign = Stack frame produced ( REF STRING s1 , STRING s2 ) VOID : BEGIN INT i := 0 ; WHILE i < string_size AND s2 [ i ] /= REPR 0 DO s1 [ i ] := s2 [ i ] ; i := i + 1 OD ; s1 [ i ] := s2 [ i ] ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30: * other instruction StrAssign 30: ; PROC StrTail = Stack frame produced ( REF STRING s1 , STRING s2 , INT pos ) VOID : BEGIN INT i := 0 ; WHILE i + pos < string_size AND s2 [ i + pos ] /= REPR 0 DO s1 [ i ] := s2 [ i + pos ] ; i := i + 1 OD ; s1 [ i ] := s2 [ i + pos ] ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34: * other instruction StrTail 34: ; PROC StrSlice = Stack frame produced ( REF STRING t , STRING s , INT start , INT end ) VOID : BEGIN INT k := start ; WHILE k < string_size AND k <= end DO t [ k - start ] := s [ k ] ; k := k + 1 OD ; t [ k - start ] := REPR 0 ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30: * other instruction StrSlice 30: ; PROC StrAppend = Stack frame produced ( REF STRING s , STRING s1 , STRING s2 ) VOID : BEGIN STRING t ; INT i := 0 , j := 0 ; WHILE i < string_size AND s1 [ i ] /= REPR 0 DO t [ j ] := s1 [ i ] ; i := i + 1 ; j := j + 1 OD ; i := 0 ; WHILE i < string_size AND s2 [ i ] /= REPR 0 DO t [ j ] := s2 [ i ] ; i := i + 1 ; j := j + 1 OD ; t [ j ] := REPR 0 ; StrAssign ( s , t ) ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53: * other instruction StrAppend 53: ; PROC store_token = Stack frame produced ( INT id , STRING descr ) VOID : BEGIN id OF token := id ; StrAssign ( descr OF token , descr ) ; line OF token := line ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20: * other instruction store_token 20: ; PROC GetTokenId = Stack frame produced VOID : BEGIN StrAssign ( descr OF token , "RESERVED" ) ; IF StrEqual ( str OF token , "REF" ) THEN id OF token := tk_REF ; ELIF StrEqual ( str OF token , "LOC" ) THEN id OF token := tk_LOC ; ELIF StrEqual ( str OF token , "STRUCT" ) THEN id OF token := tk_STRUCT ; ELIF StrEqual ( str OF token , "TRUE" ) THEN id OF token := tk_TRUE ; ELIF StrEqual ( str OF token , "FALSE" ) THEN id OF token := tk_FALSE ; ELIF StrEqual ( str OF token , "NIL" ) THEN id OF token := tk_NIL ; ELIF StrEqual ( str OF token , "ABS" ) THEN id OF token := tk_ABS ; ELIF StrEqual ( str OF token , "NOT" ) THEN id OF token := tk_NOT ; ELIF StrEqual ( str OF token , "AND" ) THEN id OF token := tk_AND ; ELIF StrEqual ( str OF token , "OR" ) THEN id OF token := tk_OR ; ELIF StrEqual ( str OF token , "AND" ) THEN id OF token := tk_AND ; ELIF StrEqual ( str OF token , "OR" ) THEN id OF token := tk_OR ; ELIF StrEqual ( str OF token , "IS" ) THEN id OF token := tk_IS ; ELIF StrEqual ( str OF token , "ISNT" ) THEN id OF token := tk_ISNT ; ELIF StrEqual ( str OF token , "OF" ) THEN id OF token := tk_OF ; ELIF StrEqual ( str OF token , "BEGIN" ) THEN id OF token := tk_BEGIN ; ELIF StrEqual ( str OF token , "END" ) THEN id OF token := tk_END ; ELIF StrEqual ( str OF token , "IF" ) THEN id OF token := tk_IF ; ELIF StrEqual ( str OF token , "THEN" ) THEN id OF token := tk_THEN ; ELIF StrEqual ( str OF token , "ELSE" ) THEN id OF token := tk_ELSE ; ELIF StrEqual ( str OF token , "ELIF" ) THEN id OF token := tk_ELIF ; ELIF StrEqual ( str OF token , "FI" ) THEN id OF token := tk_FI ; ELIF StrEqual ( str OF token , "FOR" ) THEN id OF token := tk_FOR ; ELIF StrEqual ( str OF token , "FROM" ) THEN id OF token := tk_FROM ; ELIF StrEqual ( str OF token , "BY" ) THEN id OF token := tk_BY ; ELIF StrEqual ( str OF token , "TO" ) THEN id OF token := tk_TO ; ELIF StrEqual ( str OF token , "WHILE" ) THEN id OF token := tk_WHILE ; ELIF StrEqual ( str OF token , "DO" ) THEN id OF token := tk_DO ; ELIF StrEqual ( str OF token , "OD" ) THEN id OF token := tk_OD ; ELIF StrEqual ( str OF token , "PROC" ) THEN id OF token := tk_PROC ; ELIF StrEqual ( str OF token , "MODE" ) THEN id OF token := tk_MODE ; ELIF StrEqual ( str OF token , "LWB" ) THEN id OF token := tk_LWB ; ELIF StrEqual ( str OF token , "UPB" ) THEN id OF token := tk_UPB ; ELIF StrEqual ( str OF token , "REPR" ) THEN id OF token := tk_REPR ; ELIF StrEqual ( str OF token , "FORWARD" ) THEN id OF token := tk_FORWARD ; ELIF StrEqual ( str OF token , "MOD" ) THEN id OF token := tk_MOD ; ELIF StrUCase ( str OF token ) THEN store_token ( tk_AMODE , "AMODE" ) ; ELSE store_token ( tk_ID , "IDENTIFIER" ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254:255:256:257:258:259:260:261:262:263:264:265:266:267:268:269:270:271:272:273:274:275:276:277:278:279:280:281:282:283:284:285:286:287:288:289:290:291:292:293:294:295:296:297:298:299:300:301:302:303:304:305:306:307:308:309:310:311:312:313:314:315:316:317:318:319:320:321:322:323:324:325:326:327:328:329:330:331:332:333:334:335:336:337:338:339:340:341:342:343:344:345:346:347:348:349:350:351:352:353: * other instruction GetTokenId 353: ; PROC IsSeparator = Stack frame produced ( CHAR ch ) BOOL : BEGIN BOOL result ; IF ( ch = ( ) OR ( ch = ) ) OR ( ch = [ ) OR ( ch = ] ) OR ( ch = : ) OR ( ch = ; ) OR ( ch = , ) OR ( ch = * ) OR ( ch = + ) OR ( ch = - ) OR ( ch = = ) OR ( ch = / ) OR ( ch = > ) OR ( ch = < ) OR ( ch = | ) THEN result := TRUE ELSE result := FALSE FI ; result END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49: * other instruction IsSeparator 49: ; PROC IsBlank = Stack frame produced ( CHAR ch ) BOOL : BEGIN BOOL result ; IF ch <= AND ch /= REPR tk_EOF THEN result := TRUE ELSE result := FALSE FI ; result END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24: * other instruction IsBlank 24: ; PROC IsNumber = Stack frame produced ( CHAR ch ) BOOL : BEGIN BOOL result ; IF ( ch >= 0 ) AND ( ch <= 9 ) THEN result := TRUE ELSE result := FALSE FI ; result END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23: * other instruction IsNumber 23: ; PROC IsIdChar = Stack frame produced ( CHAR ch ) BOOL : BEGIN BOOL result ; IF ( ( ch >= A ) AND ( ch <= Z ) ) OR ( ( ch >= a ) AND ( ch <= z ) ) OR IsNumber ( ch ) OR ( ch = _ ) THEN result := TRUE ELSE result := FALSE FI ; result END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32: * other instruction IsIdChar 32: ; PROC GetSeparator = Stack frame produced VOID : BEGIN IF nextChar = : THEN nextChar := read ; IF nextChar = = THEN store_token ( tk_ASSIGN , "ASSIGN" ) ; StrAssign ( str OF token , ":=" ) ; nextChar := read ; ELSE store_token ( tk_COLON , "COLON" ) ; StrAssign ( str OF token , ":" ) ; FI ; ELIF nextChar = < THEN nextChar := read ; IF nextChar = = THEN store_token ( tk_LEQ , "LEQ" ) ; StrAssign ( str OF token , "<=" ) ; nextChar := read ; ELSE store_token ( tk_LESS , "LESS" ) ; StrAssign ( str OF token , "<" ) ; FI ; ELIF nextChar = > THEN nextChar := read ; IF nextChar = = THEN store_token ( tk_GEQ , "GEQ" ) ; StrAssign ( str OF token , ">=" ) ; nextChar := read ; ELSE store_token ( tk_GREATER , "GREATER" ) ; StrAssign ( str OF token , ">" ) ; FI ; ELIF nextChar = / THEN nextChar := read ; IF nextChar = = THEN store_token ( tk_NEQ , "NEQ" ) ; StrAssign ( str OF token , "/=" ) ; nextChar := read ; ELSE store_token ( tk_DIV , "DIV" ) ; StrAssign ( str OF token , "/" ) ; FI ; ELIF nextChar = = THEN nextChar := read ; store_token ( tk_EQUAL , "EQUAL" ) ; StrAssign ( str OF token , "=" ) ; ELIF nextChar = * THEN nextChar := read ; IF nextChar = * THEN store_token ( tk_POWER , "POWER" ) ; StrAssign ( str OF token , "**" ) ; nextChar := read ; ELSE store_token ( tk_MULT , "MULT" ) ; StrAssign ( str OF token , "*" ) ; FI ; ELIF nextChar = + THEN nextChar := read ; store_token ( tk_PLUS , "PLUS" ) ; StrAssign ( str OF token , "+" ) ; ELIF nextChar = - THEN nextChar := read ; store_token ( tk_MINUS , "MINUS" ) ; StrAssign ( str OF token , "-" ) ; ELIF nextChar = | THEN nextChar := read ; store_token ( tk_PIPE , "PIPE" ) ; StrAssign ( str OF token , "|" ) ; ELIF nextChar = [ THEN nextChar := read ; store_token ( tk_LBRACKET , "LBRACKET" ) ; StrAssign ( str OF token , "[" ) ; ELIF nextChar = ] THEN nextChar := read ; store_token ( tk_RBRACKET , "RBRACKET" ) ; StrAssign ( str OF token , "]" ) ; ELIF nextChar = ( THEN nextChar := read ; store_token ( tk_LPARENTH , "LPARENTH" ) ; StrAssign ( str OF token , "(" ) ; ELIF nextChar = ) THEN nextChar := read ; store_token ( tk_RPARENTH , "RPARENTH" ) ; StrAssign ( str OF token , ")" ) ; ELIF nextChar = ; THEN nextChar := read ; store_token ( tk_SEMICOLON , "SEMICOLON" ) ; StrAssign ( str OF token , ";" ) ; ELIF nextChar = , THEN nextChar := read ; store_token ( tk_COMMA , "COMMA" ) ; StrAssign ( str OF token , "," ) ; ELSE printf ( "UNEXPECTED ERROR!\n" ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254:255:256:257:258:259:260:261:262:263:264:265:266:267:268:269:270:271:272:273:274:275:276:277:278:279:280:281: * other instruction GetSeparator 281: ; PROC GetNextToken = Stack frame produced VOID : BEGIN INT i := 0 ; IF debug_stepwise THEN debugger ; FI ; WHILE IsBlank ( nextChar ) OR nextChar = # DO WHILE IsBlank ( nextChar ) DO nextChar := read ; OD ; IF nextChar = # THEN nextChar := read ; WHILE nextChar /= DO nextChar := read OD ; nextChar := read ; ELIF nextChar = @ THEN nextChar := read ; IF nextChar = + THEN debug_echo := TRUE ; nextChar := read ; ELIF nextChar = - THEN debug_echo := FALSE ; nextChar := read ; ELSE debugger ; FI ; FI ; OD ; IF nextChar = REPR tk_EOF THEN store_token ( tk_EOF , "EOF" ) ; ELIF IsSeparator ( nextChar ) THEN GetSeparator ; ELIF nextChar = " THEN store_token ( tk_STRCONST , "STRCONST" ) ; ( str OF token ) [ i ] := nextChar ; i := i + 1 ; nextChar := read ; WHILE nextChar /= " DO ( str OF token ) [ i ] := nextChar ; i := i + 1 ; IF nextChar = \ THEN ( str OF token ) [ i ] := read ; i := i + 1 ; FI ; nextChar := read ; OD ; ( str OF token ) [ i ] := nextChar ; ( str OF token ) [ i + 1 ] := REPR 0 ; nextChar := read ; ELIF nextChar = ' THEN nextChar := read ; IF nextChar = \ THEN nextChar := read ; IF nextChar = ' OR nextChar = " OR nextChar = \ THEN ( str OF token ) [ 0 ] := nextChar ; ELIF nextChar = t THEN ( str OF token ) [ 0 ] := REPR 9 ; ELIF nextChar = n THEN ( str OF token ) [ 0 ] := REPR 10 ; ELSE error ( "Invalid char constant!" ) ; FI ; ELSE ( str OF token ) [ 0 ] := nextChar ; FI ; nextChar := read ; IF nextChar /= ' THEN error ( "Invalid char constant!" ) ; ELSE ( str OF token ) [ 1 ] := REPR 0 ; store_token ( tk_CHARCONST , "CHARCONST" ) ; FI ; nextChar := read ; ELIF IsNumber ( nextChar ) THEN store_token ( tk_INTCONST , "INTCONST" ) ; WHILE IsNumber ( nextChar ) DO ( str OF token ) [ i ] := nextChar ; i := i + 1 ; nextChar := read ; OD ; ( str OF token ) [ i ] := REPR 0 ; ELIF IsIdChar ( nextChar ) THEN WHILE IsIdChar ( nextChar ) DO ( str OF token ) [ i ] := nextChar ; i := i + 1 ; nextChar := read ; OD ; ( str OF token ) [ i ] := REPR 0 ; GetTokenId ; ELSE store_token ( tk_ERROR , "ERROR" ) ; ( str OF token ) [ 0 ] := nextChar ; ( str OF token ) [ 1 ] := REPR 0 ; nextChar := read ; FI ; used OF token := FALSE ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254: * other instruction GetNextToken 254: ; FORWARD PROC generate_code = VOID ; FORWARD PROC process_frame = VOID ; FORWARD PROC lookup = ( STRING name ) INT ; INT stack_bound = 3000 ; INT proc_info_bound = 1000 ; INT temps_bound = 1000 ; INT rule_assign = 1 ; INT rule_identity = 2 ; INT rule_itemize = 3 ; INT context_firm = 1 ; INT context_strong = 2 ; INT context_meek = 3 ; INT context_week = 4 ; INT context_soft = 5 ; INT entity_empty = 0 ; INT entity_frame = 1 ; INT entity_var = 2 ; INT entity_tempvar = 3 ; INT entity_ptrvar = 4 ; INT entity_argvar = 5 ; INT entity_param = 6 ; INT entity_constant = 7 ; INT entity_proc = 8 ; INT entity_mode = 9 ; INT entity_label = 10 ; INT entity_startscope = 11 ; INT entity_endscope = 12 ; INT max_nesting = 10 ; INT max_gtemps = 10 ; INT max_files = 5 ; INT max_params = 10 ; STRING dummy ; INT table_strings_bound = 20000 ; [ table_strings_bound ] CHAR table_strings ; INT current_stroffset := 0 ; INT current_strindex := 0 ; MODE PROCINFO = STRUCT ( STRING label , INT quadptr , [ temps_bound ] BOOL temps_used , INT max_temp , BOOL done ) ; [ proc_info_bound ] PROCINFO table_proc_info ; INT proc_info_index := 0 ; INT current_proc := 0 ; INT current_nesting := 0 ; MODE ENTITY = STRUCT ( INT type , STRING name , STRING value , INT nesting , INT id , INT proc_info , INT scopeptr , STRING mode , INT mode_size , INT storage_type , INT addr_offset , INT reg ) ; [ stack_bound ] ENTITY stack ; INT stack_index := 1 ; INT current_scope_start := 1 ; INT arg_count := 0 ; INT label_count := 0 ; INT quad_index := 0 ; PROC align = Stack frame produced ( INT n ) INT : BEGIN INT i ; IF n MOD 8 = 0 THEN i := n ELSE i := 8 * ( n / 8 + 1 ) FI ; i END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38: * other instruction align 38: ; PROC set_next_proc = Stack frame produced VOID : BEGIN current_proc := proc_info_index ; WHILE current_proc > 0 AND done OF table_proc_info [ current_proc ] DO current_proc := current_proc - 1 ; OD ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36: * other instruction set_next_proc 36: ; PROC reset_temps = Stack frame produced VOID : BEGIN INT i := 0 ; max_temp OF table_proc_info [ proc_info_index ] := 0 ; WHILE i < temps_bound DO ( temps_used OF table_proc_info [ proc_info_index ] ) [ i ] := FALSE ; i := i + 1 ; OD ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40: * other instruction reset_temps 40: ; PROC get_next_temp = Stack frame produced INT : BEGIN INT i := 0 ; WHILE i < temps_bound AND ( temps_used OF table_proc_info [ current_proc ] ) [ i ] DO i := i + 1 ; OD ; IF i = temps_bound THEN error ( "Temporary variables exhausted!" ) ; FI ; IF i > max_temp OF table_proc_info [ current_proc ] THEN max_temp OF table_proc_info [ current_proc ] := max_temp OF table_proc_info [ current_proc ] + 1 ; FI ; ( temps_used OF table_proc_info [ current_proc ] ) [ i ] := TRUE ; i END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57: * other instruction get_next_temp 57: ; PROC reset_args = Stack frame produced VOID : BEGIN arg_count := 0 ; END Generating code... Stack frame produced 23:24:25:26: * other instruction reset_args 26: ; PROC get_arg_temp = Stack frame produced INT : BEGIN INT i := arg_count ; arg_count := arg_count + 1 ; i END Generating code... Stack frame produced 23:24:25:26:27:28: * other instruction get_arg_temp 28: ; PROC free_temp = Stack frame produced ( INT ptr ) VOID : BEGIN INT n ; IF type OF stack [ ptr ] = entity_tempvar OR type OF stack [ ptr ] = entity_ptrvar THEN n := id OF stack [ ptr ] ; ( temps_used OF table_proc_info [ current_proc ] ) [ n ] := FALSE ; IF debug_echo THEN printf ( "\nTemp %i freed\n" , n ) ; FI ; ELSE IF debug_echo THEN printf ( "\nFailed to free temp!\n" ) ; FI ; FI ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53: * other instruction free_temp 53: ; PROC reset_labels = Stack frame produced VOID : BEGIN label_count := 0 ; END Generating code... Stack frame produced 23:24:25:26: * other instruction reset_labels 26: ; PROC get_next_label = Stack frame produced INT : BEGIN label_count := label_count + 1 ; label_count END Generating code... Stack frame produced 23:24:25:26:27: * other instruction get_next_label 27: ; PROC inc_stack_index = Stack frame produced VOID : BEGIN stack_index := stack_index + 1 ; IF stack_index >= stack_bound THEN printf ( "Panic: Max stack limit exceeded!\n" ) ; exit ; FI ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34: * other instruction inc_stack_index 34: ; PROC IsPrefix = Stack frame produced ( STRING s , STRING p ) BOOL : BEGIN INT i := 0 ; WHILE p [ i ] /= REPR 0 AND s [ i ] = p [ i ] DO i := i + 1 OD ; p [ i ] = REPR 0 END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42: * other instruction IsPrefix 42: ; PROC is_mode_void = Stack frame produced ( INT ptr ) BOOL : BEGIN StrEqual ( mode OF stack [ ptr ] , "VOID" ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30: * other instruction is_mode_void 30: ; PROC is_mode_array = Stack frame produced ( INT ptr ) BOOL : BEGIN IsPrefix ( mode OF stack [ ptr ] , "[" ) OR IsPrefix ( mode OF stack [ ptr ] , "REF [" ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36: * other instruction is_mode_array 36: ; PROC is_mode_struc = Stack frame produced ( INT ptr ) BOOL : BEGIN IsPrefix ( mode OF stack [ ptr ] , "(" ) OR IsPrefix ( mode OF stack [ ptr ] , "REF (" ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36: * other instruction is_mode_struc 36: ; PROC get_storage_size = Stack frame produced ( STRING m , BOOL array ) INT : BEGIN INT ptr , size ; STRING mode ; IF IsPrefix ( mode , "REF" ) THEN StrTail ( mode , m , 4 ) ; ELSE StrAssign ( mode , m ) ; FI ; IF array THEN IF StrEqual ( mode , "REF" ) THEN size := 8 ; ELIF StrEqual ( mode , "FILE" ) THEN size := 4 ; ELIF StrEqual ( mode , "INT" ) THEN size := 4 ; ELIF StrEqual ( mode , "CHAR" ) THEN size := 1 ; ELIF StrEqual ( mode , "BOOL" ) THEN size := 1 ; ELIF StrEqual ( mode , "STRING" ) THEN size := string_size ; ELIF StrEqual ( mode , "VOID" ) THEN size := 0 ; ELSE ptr := lookup ( mode ) ; size := mode_size OF stack [ ptr ] ; FI ; ELSE IF StrEqual ( mode , "REF" ) THEN size := 8 ; ELIF StrEqual ( mode , "FILE" ) THEN size := 8 ; ELIF StrEqual ( mode , "INT" ) THEN size := 8 ; ELIF StrEqual ( mode , "CHAR" ) THEN size := 8 ; ELIF StrEqual ( mode , "BOOL" ) THEN size := 8 ; ELIF StrEqual ( mode , "STRING" ) THEN size := string_size ; ELIF StrEqual ( mode , "VOID" ) THEN size := 0 ; ELSE ptr := lookup ( mode ) ; size := mode_size OF stack [ ptr ] ; FI ; FI ; size END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154: * other instruction get_storage_size 154: ; PROC get_element_size = Stack frame produced ( INT ptr ) INT : BEGIN STRING mode ; INT size ; IF is_mode_array ( ptr ) THEN StrTail ( mode , mode OF stack [ ptr ] , 3 ) ELSE StrAssign ( mode , mode OF stack [ ptr ] ) FI ; IF IsPrefix ( mode , "REF" ) THEN size := 8 ; ELIF StrEqual ( mode , "FILE" ) THEN size := 4 ; ELIF StrEqual ( mode , "INT" ) THEN size := 4 ; ELIF StrEqual ( mode , "CHAR" ) THEN size := 1 ; ELIF StrEqual ( mode , "BOOL" ) THEN size := 1 ; ELIF StrEqual ( mode , "STRING" ) THEN size := string_size ; ELSE printf ( "get_element_size: mode %s not implemented!\n" , mode ) ; error ( "" ) ; FI ; size END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91: * other instruction get_element_size 91: ; PROC get_storage_code = Stack frame produced ( INT ptr ) CHAR : BEGIN STRING mode ; CHAR code ; IF IsPrefix ( mode OF stack [ ptr ] , "REF" ) THEN StrTail ( mode , mode OF stack [ ptr ] , 4 ) ; ELSE StrAssign ( mode , mode OF stack [ ptr ] ) ; FI ; IF is_mode_array ( ptr ) THEN StrTail ( mode , mode , StrFind ( mode , ] , 0 ) + 2 ) ; FI ; IF IsPrefix ( mode , "REF" ) THEN code := O ; ELIF StrEqual ( mode , "INT" ) THEN code := T ; ELIF StrEqual ( mode , "CHAR" ) THEN code := B ; ELIF StrEqual ( mode , "BOOL" ) THEN code := B ; ELIF StrEqual ( mode , "STRING" ) THEN code := B ; ELSE printf ( "get_storage_code: non-primitive mode _%s_\n" , mode ) ; error ( "" ) ; FI ; code END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100: * other instruction get_storage_code 100: ; PROC deref_mode = Stack frame produced ( STRING source_mode , STRING target_mode ) INT : BEGIN STRING mode ; INT count := 0 ; StrAssign ( mode , source_mode ) ; WHILE NOT StrEqual ( mode , target_mode ) AND IsPrefix ( mode , "REF" ) DO count := count + 1 ; StrTail ( mode , mode , 4 ) ; OD ; IF NOT StrEqual ( mode , target_mode ) THEN count := - 1 ; FI ; count END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55: * other instruction deref_mode 55: ; PROC check_mode = Stack frame produced ( INT ptr , STRING mode ) BOOL : BEGIN deref_mode ( mode OF stack [ ptr ] , mode ) >= 0 END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31: * other instruction check_mode 31: ; PROC accept_mode = Stack frame produced ( INT ptr , STRING mode ) VOID : BEGIN IF NOT check_mode ( ptr , mode ) THEN printf ( "Expected mode %s and found %s! " , mode , mode OF stack [ ptr ] ) ; error ( "Incompatible modes!" ) FI ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40: * other instruction accept_mode 40: ; PROC is_mode_composite = Stack frame produced ( INT ptr ) BOOL : BEGIN check_mode ( ptr , "STRING" ) OR is_mode_array ( ptr ) OR is_mode_struc ( ptr ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34: * other instruction is_mode_composite 34: ; PROC is_mode_ref = Stack frame produced ( INT ptr ) BOOL : BEGIN IsPrefix ( mode OF stack [ ptr ] , "REF" ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30: * other instruction is_mode_ref 30: ; PROC StrMatchPrefix = Stack frame produced ( REF STRING str , STRING prefix ) INT : BEGIN STRING tmp ; INT j := 0 ; WHILE prefix [ j ] /= REPR 0 AND prefix [ j ] = str [ j ] DO IF str [ j ] = [ THEN StrSlice ( tmp , str , 0 , j ) ; StrTail ( str , str , StrFind ( str , ] , j ) ) ; StrAppend ( str , tmp , str ) ; FI ; j := j + 1 ; OD ; j END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60: * other instruction StrMatchPrefix 60: ; PROC unify = Stack frame produced ( REF STRING lmode , REF STRING rmode , REF STRING mode ) VOID : BEGIN STRING prefix ; INT i , j , n ; BOOL found ; IF IsPrefix ( mode , "{}" ) AND NOT IsPrefix ( rmode , "REF" ) AND NOT IsPrefix ( rmode , "(" ) AND NOT IsPrefix ( rmode , "[" ) THEN StrAppend ( lmode , lmode , rmode ) ; StrAssign ( mode , "" ) ; ELIF IsPrefix ( mode , "{" ) THEN i := 1 ; n := StrLen ( mode ) ; found := FALSE ; WHILE i < n AND NOT found DO j := StrFind ( mode , , , i ) ; IF j = n THEN StrSlice ( prefix , mode , i , j - 2 ) ; ELSE StrSlice ( prefix , mode , i , j - 1 ) ; FI ; IF StrEqual ( rmode , prefix ) THEN StrAppend ( lmode , lmode , prefix ) ; StrAssign ( mode , "" ) ; found := TRUE ; FI ; i := j + 1 ; OD ; ELSE i := StrMatchPrefix ( rmode , mode ) ; StrSlice ( prefix , rmode , 0 , i - 1 ) ; StrAppend ( lmode , lmode , prefix ) ; StrTail ( rmode , rmode , i ) ; StrTail ( mode , mode , i ) ; FI ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131: * other instruction unify 131: ; PROC unify_labels = Stack frame produced ( INT target , INT source ) VOID : BEGIN id OF stack [ target ] := id OF stack [ source ] ; StrAssign ( name OF stack [ target ] , name OF stack [ source ] ) ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37: * other instruction unify_labels 37: ; PROC get_proc_mode = Stack frame produced ( INT proc , REF STRING mode ) VOID : BEGIN StrTail ( mode , mode OF stack [ proc ] , StrFind ( mode OF stack [ proc ] , : , 0 ) + 1 ) ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38: * other instruction get_proc_mode 38: ; PROC get_param_mode = Stack frame produced ( INT proc , INT rank , REF STRING mode ) VOID : BEGIN STRING pmode ; INT pos , k , count := rank - 1 ; StrAssign ( pmode , mode OF stack [ proc ] ) ; pos := StrFind ( pmode , ( , 0 ) + 1 ; k := pos ; WHILE count > 0 DO IF pmode [ pos ] = | THEN count := count - 1 ; pos := pos + 1 ; k := pos ; FI ; pos := pos + 1 ; OD ; StrSlice ( mode , pmode , k , StrFind ( pmode , | , k ) - 1 ) ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65: * other instruction get_param_mode 65: ; PROC get_next_field = Stack frame produced ( REF STRING fieldmode , REF STRING fieldname , STRING mode , INT pos ) INT : BEGIN INT paren ; INT i := pos ; INT j ; IF mode [ i ] = ( THEN paren := 1 ; i := i + 1 ; WHILE paren > 0 DO IF mode [ i ] = ( THEN paren := paren + 1 ; ELIF mode [ i ] = ) THEN paren := paren - 1 ; FI ; i := i + 1 ; OD ; ELSE WHILE mode [ i ] < a OR mode [ i ] > z DO i := i + 1 ; OD ; FI ; StrSlice ( fieldmode , mode , pos , i - 2 ) ; WHILE mode [ i ] = DO i := i + 1 ; OD ; j := i ; WHILE mode [ i ] /= ) AND mode [ i ] /= , DO i := i + 1 ; OD ; StrSlice ( fieldname , mode , j , i - 1 ) ; IF mode [ i ] = ) THEN i := - 1 ; ELSE i := i + 1 ; FI ; i END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107: * other instruction get_next_field 107: ; PROC calc_mode_size = Stack frame produced ( STRING source_mode , BOOL array ) INT : BEGIN INT size , k , pos ; STRING next_mode , mode , field , items ; INT ptr ; IF IsPrefix ( source_mode , "REF" ) THEN StrTail ( mode , source_mode , 4 ) ; ELSE StrAssign ( mode , source_mode ) ; FI ; IF IsPrefix ( mode , "[" ) THEN k := StrFind ( mode , [ , 0 ) ; pos := StrFind ( mode , ] , 0 ) ; StrSlice ( items , mode , k + 1 , pos - 1 ) ; StrTail ( next_mode , mode , pos + 2 ) ; size := align ( array_header_size + str2int ( items ) * calc_mode_size ( next_mode , TRUE ) ) ; ELIF IsPrefix ( mode , "(" ) THEN pos := StrFind ( mode , ( , 0 ) + 1 ; size := struc_header_size ; WHILE pos > 0 DO pos := get_next_field ( next_mode , field , mode , pos ) ; size := size + calc_mode_size ( next_mode , FALSE ) ; OD ; ELSE IF array THEN IF IsPrefix ( mode , "REF" ) THEN size := 8 ; ELIF StrEqual ( mode , "FILE" ) THEN size := 4 ; ELIF StrEqual ( mode , "INT" ) THEN size := 4 ; ELIF StrEqual ( mode , "CHAR" ) THEN size := 1 ; ELIF StrEqual ( mode , "BOOL" ) THEN size := 1 ; ELIF StrEqual ( mode , "STRING" ) THEN size := string_size ; ELIF StrEqual ( mode , "VOID" ) OR StrEqual ( mode , "?" ) THEN size := 0 ; ELSE ptr := lookup ( mode ) ; size := calc_mode_size ( mode OF stack [ ptr ] , FALSE ) ; FI ; ELSE IF IsPrefix ( mode , "REF" ) THEN size := 8 ; ELIF StrEqual ( mode , "FILE" ) THEN size := 8 ; ELIF StrEqual ( mode , "INT" ) THEN size := 8 ; ELIF StrEqual ( mode , "CHAR" ) THEN size := 8 ; ELIF StrEqual ( mode , "BOOL" ) THEN size := 8 ; ELIF StrEqual ( mode , "STRING" ) THEN size := string_size ; ELIF StrEqual ( mode , "VOID" ) OR StrEqual ( mode , "?" ) THEN size := 0 ; ELSE ptr := lookup ( mode ) ; size := calc_mode_size ( mode OF stack [ ptr ] , FALSE ) ; FI ; FI ; FI ; size END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235: * other instruction calc_mode_size 235: ; PROC calc_mode_items = Stack frame produced ( STRING mode ) INT : BEGIN INT i , j ; STRING items ; IF IsPrefix ( mode , "[" ) OR IsPrefix ( mode , "REF [" ) THEN i := StrFind ( mode , [ , 0 ) ; j := StrFind ( mode , ] , i ) ; StrSlice ( items , mode , i + 1 , j - 1 ) ; ELSE printf ( "calc_mode_items: %s not an array!" , mode ) ; error ( "" ) ; FI ; str2int ( items ) END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61: * other instruction calc_mode_items 61: ; PROC match = Stack frame produced ( STRING strucmode , STRING fieldname , INT start ) INT : BEGIN INT i := start ; INT j := 0 ; WHILE fieldname [ j ] /= REPR 0 AND fieldname [ j ] = strucmode [ i ] DO j := j + 1 ; i := i + 1 ; OD ; IF NOT ( fieldname [ j ] = REPR 0 AND ( strucmode [ i ] = REPR 0 OR strucmode [ i ] = , OR strucmode [ i ] = ) ) ) THEN i := - 1 ; FI ; i END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60: * other instruction match 60: ; PROC calc_field_offset = Stack frame produced ( STRING mode , STRING name ) INT : BEGIN STRING fieldmode , field ; INT pos := StrFind ( mode , ( , 0 ) + 1 ; INT offset := struc_header_size ; WHILE pos > 0 DO pos := get_next_field ( fieldmode , field , mode , pos ) ; IF StrEqual ( field , name ) THEN pos := 0 ; ELSE offset := offset + calc_mode_size ( fieldmode , FALSE ) ; FI ; OD ; offset END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56: * other instruction calc_field_offset 56: ; PROC find_field = Stack frame produced ( REF STRING strucmode , STRING fieldname , REF STRING fieldmode ) BOOL : BEGIN STRING alias , mode , field ; BOOL found := FALSE ; INT paren , pos , k ; INT i ; INT ptr ; IF IsPrefix ( strucmode , "REF" ) THEN i := 4 ; StrSlice ( fieldmode , strucmode , 0 , i - 1 ) ; ELSE i := 0 ; FI ; IF strucmode [ i ] /= ( THEN StrTail ( alias , strucmode , i ) ; strucmode [ i ] := REPR 0 ; ptr := lookup ( alias ) ; StrAppend ( strucmode , strucmode , mode OF stack [ ptr ] ) ; FI ; i := i + 1 ; k := i ; WHILE strucmode [ i ] /= REPR 0 AND NOT found DO IF strucmode [ i ] = ( THEN paren := 1 ; i := i + 1 ; WHILE paren > 0 DO IF strucmode [ i ] = ( THEN paren := paren + 1 ; ELIF strucmode [ i ] = ) THEN paren := paren - 1 ; FI ; i := i + 1 ; OD ; FI ; IF strucmode [ i ] >= a AND strucmode [ i ] <= z THEN pos := match ( strucmode , fieldname , i ) ; IF pos = - 1 THEN WHILE NOT ( strucmode [ i ] = , OR strucmode [ i ] = ) ) DO i := i + 1 ; OD ; IF strucmode [ i ] = , THEN i := i + 1 ; k := i ; FI ; ELSE StrSlice ( mode , strucmode , k , i - 2 ) ; StrAppend ( fieldmode , fieldmode , mode ) ; found := TRUE ; FI ; ELSE i := i + 1 ; FI ; OD ; found END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152: * other instruction find_field 152: ; PROC set_fieldvar = Stack frame produced ( INT struc , INT field ) VOID : BEGIN STRING fieldmode ; STRING tmp ; IF NOT find_field ( mode OF stack [ struc ] , name OF stack [ field ] , fieldmode ) THEN printf ( "Field %s not found in structure %s!" , name OF stack [ field ] , mode OF stack [ struc ] ) ; error ( "" ) FI ; type OF stack [ field ] := entity_ptrvar ; StrAssign ( mode OF stack [ field ] , fieldmode ) ; mode_size OF stack [ field ] := calc_mode_size ( fieldmode , FALSE ) ; addr_offset OF stack [ field ] := calc_field_offset ( mode OF stack [ struc ] , name OF stack [ field ] ) ; id OF stack [ field ] := get_next_temp ; int2str ( id OF stack [ field ] , tmp ) ; StrAppend ( name OF stack [ field ] , "%" , tmp ) ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86: * other instruction set_fieldvar 86: ; PROC record_string = Stack frame produced ( STRING name ) INT : BEGIN INT offset := current_stroffset ; INT i ; IF StrLen ( name ) > 2 THEN table_strings [ current_strindex ] := name [ 0 ] ; current_strindex := current_strindex + 1 ; current_stroffset := current_stroffset + 1 ; i := 1 ; WHILE name [ i + 1 ] /= REPR 0 DO IF name [ i ] = " THEN table_strings [ current_strindex ] := " ; table_strings [ current_strindex + 1 ] := , ; table_strings [ current_strindex + 2 ] := ' ; table_strings [ current_strindex + 3 ] := " ; table_strings [ current_strindex + 4 ] := ' ; table_strings [ current_strindex + 5 ] := , ; table_strings [ current_strindex + 6 ] := " ; current_strindex := current_strindex + 7 ; current_stroffset := current_stroffset + 1 ; i := i + 1 ; ELSE table_strings [ current_strindex ] := name [ i ] ; current_strindex := current_strindex + 1 ; current_stroffset := current_stroffset + 1 ; i := i + 1 ; FI ; OD ; table_strings [ current_strindex ] := name [ i ] ; table_strings [ current_strindex + 1 ] := name [ i + 1 ] ; current_strindex := current_strindex + 2 ; current_stroffset := align ( current_stroffset + 8 ) ; ELSE offset := current_stroffset - 8 ; FI ; offset END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106: * other instruction record_string 106: ; PROC new_mode = Stack frame produced ( STRING name , STRING mode ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_mode ; StrAssign ( name OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56: * other instruction new_mode 56: ; PROC new_var = Stack frame produced ( STRING name , STRING mode ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_var ; StrAssign ( name OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56: * other instruction new_var 56: ; PROC new_tempvar = Stack frame produced ( STRING mode ) INT : BEGIN STRING tmp ; INT ptr := stack_index ; type OF stack [ stack_index ] := entity_tempvar ; id OF stack [ stack_index ] := get_next_temp ; int2str ( id OF stack [ stack_index ] , tmp ) ; StrAppend ( name OF stack [ stack_index ] , "%" , tmp ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66: * other instruction new_tempvar 66: ; PROC new_argvar = Stack frame produced ( STRING mode ) INT : BEGIN STRING tmp ; INT ptr := stack_index ; type OF stack [ stack_index ] := entity_argvar ; id OF stack [ stack_index ] := get_arg_temp ; int2str ( id OF stack [ stack_index ] , tmp ) ; StrAppend ( name OF stack [ stack_index ] , "&" , tmp ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63: * other instruction new_argvar 63: ; PROC new_param = Stack frame produced ( STRING name , STRING mode ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_param ; StrAssign ( name OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56: * other instruction new_param 56: ; PROC new_const = Stack frame produced ( STRING name , STRING mode ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_constant ; StrAssign ( name OF stack [ stack_index ] , name ) ; StrAssign ( value OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := current_nesting ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := calc_mode_size ( mode , FALSE ) ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61: * other instruction new_const 61: ; PROC new_charconst = Stack frame produced ( STRING name ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_constant ; ( name OF stack [ stack_index ] ) [ 0 ] := ' ; ( name OF stack [ stack_index ] ) [ 1 ] := name [ 0 ] ; ( name OF stack [ stack_index ] ) [ 2 ] := ' ; StrAssign ( value OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := - 1 ; StrAssign ( mode OF stack [ stack_index ] , "CHAR" ) ; mode_size OF stack [ stack_index ] := 0 ; addr_offset OF stack [ stack_index ] := 0 ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67: * other instruction new_charconst 67: ; PROC new_strconst = Stack frame produced ( STRING name ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_constant ; StrAssign ( name OF stack [ stack_index ] , name ) ; StrAssign ( value OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := - 1 ; StrAssign ( mode OF stack [ stack_index ] , "STRING" ) ; mode_size OF stack [ stack_index ] := string_size ; addr_offset OF stack [ stack_index ] := record_string ( name ) ; reg OF stack [ stack_index ] := - 1 ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61: * other instruction new_strconst 61: ; PROC new_label = Stack frame produced INT : BEGIN STRING lbl ; INT ptr := stack_index ; type OF stack [ stack_index ] := entity_label ; id OF stack [ stack_index ] := get_next_label ; int2str ( id OF stack [ stack_index ] , lbl ) ; StrAppend ( name OF stack [ stack_index ] , "L" , lbl ) ; nesting OF stack [ stack_index ] := current_nesting ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48: * other instruction new_label 48: ; PROC new_fixedlabel = Stack frame produced ( STRING label ) INT : BEGIN STRING lbl ; INT ptr := stack_index ; type OF stack [ stack_index ] := entity_label ; StrAssign ( name OF stack [ stack_index ] , label ) ; nesting OF stack [ stack_index ] := current_nesting ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38: * other instruction new_fixedlabel 38: ; PROC new_proc = Stack frame produced ( STRING name ) INT : BEGIN INT ptr := stack_index ; type OF stack [ stack_index ] := entity_proc ; StrAssign ( name OF stack [ stack_index ] , name ) ; StrAssign ( mode OF stack [ stack_index ] , "" ) ; nesting OF stack [ stack_index ] := current_nesting + 1 ; proc_info_index := proc_info_index + 1 ; IF proc_info_index >= proc_info_bound THEN error ( "Procedure entries maximum exceeded!" ) ; FI ; current_proc := proc_info_index ; proc_info OF stack [ stack_index ] := proc_info_index ; quadptr OF table_proc_info [ proc_info_index ] := quad_index ; done OF table_proc_info [ proc_info_index ] := FALSE ; reset_temps ; inc_stack_index ; ptr END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62: * other instruction new_proc 62: ; PROC set_proc_properties = Stack frame produced ( INT ptr , INT label , STRING mode , INT mode_size ) VOID : BEGIN INT proc_info := proc_info OF stack [ ptr ] ; current_proc := proc_info ; StrAssign ( label OF table_proc_info [ proc_info ] , name OF stack [ label ] ) ; StrAssign ( mode OF stack [ ptr ] , mode ) ; mode_size OF stack [ ptr ] := mode_size ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44: * other instruction set_proc_properties 44: ; PROC runtime_proc = Stack frame produced ( STRING name , STRING label , STRING mode , INT mode_size ) VOID : BEGIN type OF stack [ stack_index ] := entity_proc ; StrAssign ( name OF stack [ stack_index ] , name ) ; nesting OF stack [ stack_index ] := current_nesting + 1 ; proc_info_index := proc_info_index + 1 ; IF proc_info_index >= proc_info_bound THEN error ( "Procedure entries maximum exceeded!" ) ; FI ; current_proc := proc_info_index ; proc_info OF stack [ stack_index ] := proc_info_index ; quadptr OF table_proc_info [ proc_info_index ] := 0 ; done OF table_proc_info [ proc_info_index ] := TRUE ; reset_temps ; StrAssign ( label OF table_proc_info [ proc_info_index ] , label ) ; StrAssign ( mode OF stack [ stack_index ] , mode ) ; mode_size OF stack [ stack_index ] := mode_size ; inc_stack_index ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69: * other instruction runtime_proc 69: ; PROC open_scope = Stack frame produced VOID : BEGIN type OF stack [ stack_index ] := entity_startscope ; StrAssign ( name OF stack [ stack_index ] , "" ) ; inc_stack_index ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34: * other instruction open_scope 34: ; PROC close_scope = Stack frame produced VOID : BEGIN type OF stack [ stack_index ] := entity_endscope ; StrAssign ( name OF stack [ stack_index ] , "" ) ; inc_stack_index ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34: * other instruction close_scope 34: ; PROC open_frame = Stack frame produced VOID : BEGIN IF current_nesting > 0 THEN process_frame ; FI ; type OF stack [ stack_index ] := entity_frame ; StrAssign ( name OF stack [ stack_index ] , "" ) ; current_nesting := current_nesting + 1 ; IF current_nesting > max_nesting THEN error ( "Maximum procedure nesting level exceeded!" ) FI ; nesting OF stack [ stack_index ] := current_nesting ; scopeptr OF stack [ stack_index ] := current_scope_start ; current_scope_start := stack_index ; inc_stack_index ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52: * other instruction open_frame 52: ; PROC close_frame = Stack frame produced VOID : BEGIN printf ( "Generating code...\n" ) ; generate_code ; stack_index := current_scope_start ; current_scope_start := scopeptr OF stack [ stack_index ] ; done OF table_proc_info [ current_proc ] := TRUE ; current_nesting := current_nesting - 1 ; set_next_proc ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39: * other instruction close_frame 39: ; PROC init_stack = Stack frame produced VOID : BEGIN type OF stack [ 0 ] := entity_empty ; StrAssign ( name OF stack [ 0 ] , "EMPTY" ) ; id OF stack [ 0 ] := - 1 ; proc_info OF stack [ 0 ] := - 1 ; scopeptr OF stack [ 0 ] := - 1 ; StrAssign ( mode OF stack [ 0 ] , "EMPTY" ) ; storage_type OF stack [ 0 ] := - 1 ; addr_offset OF stack [ 0 ] := - 1 ; reg OF stack [ 0 ] := - 1 ; END Generating code... Stack frame produced 23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62: * other instruction init_stack 62: ; PROC lookup = Stack frame produced ( STRING name ) INT : BEGIN INT enclosed ; INT index := stack_index - 1 ; WHILE index >= 1 AND NOT StrEqual ( name OF stack [ index ] , name ) DO IF type OF stack [ index ] = entity_endscope THEN enclosed := 1 ; WHILE enclosed > 0 DO index := index - 1 ; IF type OF stack [ index ] = entity_endscope THEN enclosed := enclosed + 1 ; ELIF type OF stack [ index ] = entity_startscope THEN enclosed := enclosed - 1 ; FI ; OD ; FI ; index := index - 1 ; OD ; index END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69: * other instruction lookup 69: ; PROC flookup = Stack frame produced ( STRING name ) INT : BEGIN INT index := lookup ( name ) ; IF index = 0 THEN printf ( "Symbol %s undeclared!\n" , name ) ; error ( "" ) ; FI ; index END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24: * other instruction flookup 24: ; MODE QUAD = STRUCT ( INT type , INT result , INT left , INT right ) ; INT max_tetra = 65535 ; INT max_byte = 255 ; INT quad_bound = 10000 ; INT register_bound = 200 ; INT quad_jump = 1 ; INT quad_test = 2 ; INT quad_label = 3 ; INT quad_ret = 5 ; INT quad_call = 6 ; INT quad_arg = 7 ; INT quad_proc = 8 ; INT quad_endproc = 9 ; INT quad_printn = 10 ; INT quad_printc = 11 ; INT quad_prints = 12 ; INT quad_printi = 13 ; INT quad_subscript = 14 ; INT quad_of = 15 ; INT quad_main = 16 ; INT quad_alloc = 17 ; INT quad_halt = 18 ; INT quad_upb = 19 ; INT quad_dump = 20 ; INT quad_close = 21 ; INT quad_open = 22 ; INT quad_readc = 23 ; INT quad_establish = 24 ; INT quad_argref = 25 ; INT quad_argsize = 26 ; INT quad_addstr = 27 ; INT quad_neg = 28 ; INT quad_readchar = 29 ; INT quad_alias = 30 ; INT storage_constant = 0 ; INT storage_register = 1 ; INT storage_stackframe = 2 ; INT storage_regaddr = 3 ; INT approx_code_lines := 0 ; MODE STACKFRAME = STRUCT ( INT param_size , INT localvar_size , INT retaddr_reg , INT display_reg , INT frameptr_reg ) ; [ quad_bound ] QUAD quads ; STACKFRAME stack_frame ; INT temp_regs , param_regs , var_regs , ret_regs ; PROC init_regs = Stack frame produced VOID : BEGIN temp_regs := max_temp OF table_proc_info [ current_proc ] + 1 ; param_regs := 0 ; var_regs := 0 ; ret_regs := 0 ; END Generating code... Stack frame produced 12:13:14:15:16:17:18:19:20:21: * other instruction init_regs 21: ; PROC get_param_reg = Stack frame produced INT : BEGIN param_regs := param_regs + 1 ; param_regs - 1 END Generating code... Stack frame produced 12:13:14:15:16:17: * other instruction get_param_reg 17: ; PROC get_var_reg = Stack frame produced INT : BEGIN var_regs := var_regs + 1 ; param_regs + temp_regs + var_regs - 1 END Generating code... Stack frame produced 12:13:14:15:16:17:18:19: * other instruction get_var_reg 19: ; PROC get_temp_reg = Stack frame produced ( INT offset ) INT : BEGIN param_regs + offset END Generating code... Stack frame produced 12:13:14:15: * other instruction get_temp_reg 15: ; PROC get_last_reg = Stack frame produced INT : BEGIN param_regs + temp_regs + var_regs + ret_regs END Generating code... Stack frame produced 12:13:14:15:16:17: * other instruction get_last_reg 17: ; PROC get_arg_reg = Stack frame produced INT : BEGIN arg_count := arg_count + 1 ; get_last_reg + arg_count END Generating code... Stack frame produced 12:13:14:15:16:17:18: * other instruction get_arg_reg 18: ; PROC generate_quad = Stack frame produced ( INT type , INT result , INT left , INT right ) VOID : BEGIN IF quad_index > 0 AND type OF quads [ quad_index - 1 ] = quad_label AND type = quad_label THEN unify_labels ( result , result OF quads [ quad_index - 1 ] ) ; ELSE type OF quads [ quad_index ] := type ; result OF quads [ quad_index ] := result ; left OF quads [ quad_index ] := left ; right OF quads [ quad_index ] := right ; quad_index := quad_index + 1 ; IF quad_index >= quad_bound THEN printf ( "Panic: Max quad array limit exceeded!\n" ) ; exit ; FI ; FI ; END Generating code... Stack frame produced 12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52: * other instruction generate_quad 52: ; PROC print_quad = Stack frame produced ( INT index ) VOID : BEGIN INT resptr , lptr , rptr ; INT proc_info ; STRING tmp ; resptr := result OF quads [ index ] ; lptr := left OF quads [ index ] ; rptr := right OF quads [ index ] ; IF type OF quads [ index ] = tk_ASSIGN THEN fprintf ( "ASSIGN %s := %s\n" , name OF stack [ resptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = quad_alias THEN fprintf ( "ALIAS %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_main THEN fprintf ( "MAIN\n" ) ; ELIF type OF quads [ index ] = quad_halt THEN fprintf ( "HALT\n" ) ; ELIF type OF quads [ index ] = quad_dump THEN fprintf ( "DUMPFRAME\n" ) ; ELIF type OF quads [ index ] = ABS = THEN fprintf ( "EQUAL %s = %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = ABS > THEN fprintf ( "GREATER %s > %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = ABS < THEN fprintf ( "LESS %s < %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = tk_GEQ THEN fprintf ( "GEQ %s >= %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = tk_LEQ THEN fprintf ( "LEQ %s <= %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = tk_NEQ THEN fprintf ( "NEQ %s /= %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = tk_NOT THEN fprintf ( "NOT %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_neg THEN fprintf ( "NEG -%s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = ABS + THEN fprintf ( "PLUS %s := %s + %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = ABS - THEN fprintf ( "MINUS %s := %s - %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = ABS * THEN fprintf ( "MULT %s := %s * %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = ABS / THEN fprintf ( "DIV %s := %s / %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = tk_MOD THEN fprintf ( "MOD %s := %s MOD %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = tk_OR THEN fprintf ( "OR %s := %s || %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = tk_AND THEN fprintf ( "AND %s := %s && %s\n" , name OF stack [ resptr ] , name OF stack [ lptr ] , name OF stack [ rptr ] ) ; ELIF type OF quads [ index ] = quad_subscript THEN fprintf ( "SUBSCRIPT %s[%s] -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_of THEN fprintf ( "OF %s OF %s -> %s\n" , name OF stack [ resptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_upb THEN fprintf ( "UPB %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_jump THEN fprintf ( "JUMP %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_test THEN fprintf ( "TEST %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_label THEN fprintf ( "%s: " , name OF stack [ resptr ] ) ; print_quad ( index + 1 ) ; ELIF type OF quads [ index ] = quad_printn THEN fprintf ( "PRINTn\n" ) ; ELIF type OF quads [ index ] = quad_printc THEN fprintf ( "PRINTc %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_prints THEN fprintf ( "PRINTs %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_printi THEN fprintf ( "PRINTi %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_open THEN fprintf ( "OPEN %s, %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ rptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_close THEN fprintf ( "CLOSE %s\n" , name OF stack [ lptr ] ) ; ELIF type OF quads [ index ] = quad_readc THEN fprintf ( "READC %s -> %s\n" , name OF stack [ lptr ] , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_readchar THEN fprintf ( "READCHAR -> %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_alloc THEN fprintf ( "ALLOC %s of mode %s, %i items\n" , name OF stack [ resptr ] , mode OF stack [ resptr ] , mode_size OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_ret THEN fprintf ( "RET value %s\n" , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_arg THEN fprintf ( "ARG %s of mode %s -> %s\n" , name OF stack [ lptr ] , mode OF stack [ lptr ] , mode OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_argref THEN fprintf ( "ARGREF %s of mode %s and offset %i\n" , name OF stack [ lptr ] , mode OF stack [ lptr ] , resptr - 8 ) ; ELIF type OF quads [ index ] = quad_argsize THEN fprintf ( "ARGSIZE size is %i\n" , resptr + 8 ) ; ELIF type OF quads [ index ] = quad_call THEN get_proc_mode ( lptr , tmp ) ; fprintf ( "CALL procedure %s of mode %s -> %s\n" , name OF stack [ lptr ] , tmp , name OF stack [ resptr ] ) ; ELIF type OF quads [ index ] = quad_proc THEN proc_info := proc_info OF stack [ resptr ] ; get_proc_mode ( resptr , tmp ) ; fprintf ( "PROC %s of mode %s with label %s\n" , name OF stack [ resptr ] , tmp , label OF table_proc_info [ proc_info ] ) ; ELIF type OF quads [ index ] = quad_endproc THEN fprintf ( "ENDPROC %s\n" , name OF stack [ resptr ] ) ; ELSE fprintf ( "UNKNOWN\n" , index ) ; FI ; END Generating code... Stack frame produced 12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254:255:256:257:258:259:260:261:262:263:264:265:266:267:268:269:270:271:272:273:274:275:276:277:278:279:280:281:282:283:284:285:286:287:288:289:290:291:292:293:294:295:296:297:298:299:300:301:302:303:304:305:306:307:308:309:310:311:312:313:314:315:316:317:318:319:320:321:322:323:324:325:326:327:328:329:330:331:332:333:334:335:336:337:338:339:340:341:342:343:344:345:346:347:348:349:350:351:352:353:354:355:356:357:358:359:360:361:362:363:364:365:366:367:368:369:370:371:372:373:374:375:376:377:378:379:380:381:382:383:384:385:386:387:388:389:390:391:392:393:394:395:396:397:398:399:400:401:402:403:404:405:406:407:408:409:410:411:412:413:414:415:416:417:418:419:420:421:422:423:424:425:426:427:428:429:430:431:432:433:434:435:436:437:438:439:440:441:442:443:444:445:446:447:448:449:450:451:452:453:454:455:456:457:458:459:460:461:462:463:464:465:466:467:468:469:470:471:472:473:474:475:476:477:478:479:480:481:482:483:484:485:486:487:488:489:490:491:492:493:494:495:496:497:498:499:500:501:502:503:504:505:506:507:508:509:510:511:512:513:514:515:516:517:518:519:520:521:522:523:524:525:526:527:528:529:530:531:532:533:534:535:536:537:538:539:540:541:542:543:544:545:546:547:548:549:550:551:552:553:554:555:556:557:558:559:560:561:562:563:564:565:566:567:568:569:570:571:572:573:574:575:576:577:578:579:580:581:582:583:584:585:586:587:588:589:590:591:592:593:594:595:596:597:598:599:600:601:602:603:604:605:606:607:608:609:610:611:612:613:614:615:616:617:618:619:620:621:622:623:624:625:626:627:628:629:630:631:632:633:634:635:636:637:638:639:640:641:642:643:644:645:646:647:648:649:650:651:652:653:654:655:656:657:658:659:660:661:662:663:664:665:666:667:668:669:670:671:672:673: * other instruction print_quad 673: ; PROC process_frame = Stack frame produced VOID : BEGIN INT reg ; INT index ; INT param_offset := 0 , localvar_offset := 0 ; init_regs ; index := stack_index - 1 ; WHILE type OF stack [ index ] /= entity_frame DO index := index - 1 ; OD ; IF index > 1 THEN ret_regs := 3 ; FI ; WHILE index < stack_index DO IF type OF stack [ index ] = entity_constant THEN storage_type OF stack [ index ] := storage_constant ; reg OF stack [ index ] := - 1 ; ELIF type OF stack [ index ] = entity_param AND NOT is_mode_void ( index ) THEN IF is_mode_ref ( index ) THEN storage_type OF stack [ index ] := storage_regaddr ; reg OF stack [ index ] := get_param_reg ; ELIF is_mode_composite ( index ) THEN storage_type OF stack [ index ] := storage_regaddr ; reg OF stack [ index ] := get_param_reg ; ELSE storage_type OF stack [ index ] := storage_register ; reg OF stack [ index ] := get_param_reg ; FI ; ELIF type OF stack [ index ] = entity_var AND NOT is_mode_void ( index ) THEN storage_type OF stack [ index ] := storage_stackframe ; addr_offset OF stack [ index ] := localvar_offset ; IF is_mode_array ( index ) THEN addr_offset OF stack [ index ] := addr_offset OF stack [ index ] + 8 ; FI ; localvar_offset := localvar_offset + mode_size OF stack [ index ] ; ELIF type OF stack [ index ] = entity_argvar AND NOT is_mode_void ( index ) THEN IF is_mode_composite ( index ) AND NOT is_mode_ref ( index ) THEN IF is_mode_array ( index ) THEN storage_type OF stack [ index ] := storage_regaddr ; reg OF stack [ index ] := - 1 ; ELSE storage_type OF stack [ index ] := storage_stackframe ; addr_offset OF stack [ index ] := localvar_offset ; IF is_mode_array ( index ) THEN addr_offset OF stack [ index ] := addr_offset OF stack [ index ] + 8 ; FI ; localvar_offset := localvar_offset + mode_size OF stack [ index ] ; FI ; ELSE storage_type OF stack [ index ] := storage_register ; reg OF stack [ index ] := - 1 ; FI ; ELIF type OF stack [ index ] = entity_tempvar AND NOT is_mode_void ( index ) THEN IF is_mode_composite ( index ) THEN reg OF stack [ index ] := get_temp_reg ( id OF stack [ index ] ) ; storage_type OF stack [ index ] := storage_stackframe ; addr_offset OF stack [ index ] := localvar_offset ; IF is_mode_array ( index ) THEN addr_offset OF stack [ index ] := addr_offset OF stack [ index ] + 8 ; FI ; localvar_offset := localvar_offset + mode_size OF stack [ index ] ; ELSE storage_type OF stack [ index ] := storage_register ; reg OF stack [ index ] := get_temp_reg ( id OF stack [ index ] ) ; FI ; ELIF type OF stack [ index ] = entity_ptrvar AND NOT is_mode_void ( index ) THEN storage_type OF stack [ index ] := storage_regaddr ; IF is_mode_array ( index ) THEN addr_offset OF stack [ index ] := addr_offset OF stack [ index ] + 8 ; FI ; reg OF stack [ index ] := get_temp_reg ( id OF stack [ index ] ) ; FI ; index := index + 1 ; OD ; IF ret_regs /= 0 THEN retaddr_reg OF stack_frame := get_var_reg ; display_reg OF stack_frame := get_var_reg ; frameptr_reg OF stack_frame := get_var_reg ; FI ; param_size OF stack_frame := param_offset ; localvar_size OF stack_frame := localvar_offset ; printf ( "Stack frame produced\n" ) ; IF debug_stop THEN debugger ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254:255:256:257:258:259:260:261:262:263:264:265:266:267:268:269:270:271:272:273:274:275:276:277:278:279:280:281:282:283:284:285:286:287:288: * other instruction process_frame 288: ; PROC get_bp = Stack frame produced ( INT ptr , REF STRING bp ) VOID : BEGIN IF current_nesting = nesting OF stack [ ptr ] THEN StrAssign ( bp , "fp" ) ; ELSE int2str ( nesting OF stack [ ptr ] , bp ) ; StrAppend ( bp , "disp" , bp ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31: * other instruction get_bp 31: ; PROC mmix_set = Stack frame produced ( INT x , INT val ) VOID : BEGIN IF val < 0 THEN mmix_set ( x , - val ) ; fprintf ( "\tNEGU $%i,0,$%i\n" , x , x ) ; ELSE IF val > max_tetra THEN fprintf ( "\tSETL $%i,%i&#ffff\n" , x , val ) ; fprintf ( "\tORML $%i,%i>>16\n" , x , val ) ; ELSE fprintf ( "\tSETL $%i,%i\n" , x , val ) ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45: * other instruction mmix_set 45: ; PROC mmix_sets = Stack frame produced ( STRING x , INT val ) VOID : BEGIN IF val < 0 THEN mmix_sets ( x , - val ) ; fprintf ( "\tNEGU %s,0,%s\n" , x , x ) ; ELSE IF val > max_tetra THEN fprintf ( "\tSETL %s,%i&#ffff\n" , x , val ) ; fprintf ( "\tORML %s,%i>>16\n" , x , val ) ; ELSE fprintf ( "\tSETL %s,%i\n" , x , val ) ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45: * other instruction mmix_sets 45: ; PROC mmix_add = Stack frame produced ( INT x , INT y , INT zz ) VOID : BEGIN INT z := zz ; STRING opcode ; IF z = 0 THEN IF x /= y THEN fprintf ( "\tSET $%i,$%i\n" , x , y ) ; FI ; ELSE IF z > 0 THEN StrAssign ( opcode , "ADDU" ) ELSE z := - z ; StrAssign ( opcode , "SUBU" ) ; FI ; IF z > max_byte THEN mmix_sets ( "temp1" , z ) ; fprintf ( "\t%s $%i,$%i,temp1\n" , opcode , x , y ) ; ELSE fprintf ( "\t%s $%i,$%i,%i\n" , opcode , x , y , z ) ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59: * other instruction mmix_add 59: ; PROC mmix_addssi = Stack frame produced ( STRING x , STRING y , INT zz ) VOID : BEGIN INT z := zz ; STRING opcode ; IF z = 0 THEN IF NOT StrEqual ( x , y ) THEN fprintf ( "\tSET %s,%s\n" , x , y ) ; FI ; ELSE IF z > 0 THEN StrAssign ( opcode , "ADDU" ) ELSE z := - z ; StrAssign ( opcode , "SUBU" ) ; FI ; IF z > max_byte THEN mmix_sets ( "$255" , z ) ; fprintf ( "\t%s %s,%s,$255\n" , opcode , x , y ) ; ELSE fprintf ( "\t%s %s,%s,%i\n" , opcode , x , y , z ) ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62: * other instruction mmix_addssi 62: ; PROC mmix_strappend = Stack frame produced ( INT target_symbol , INT left_symbol , INT right_symbol ) VOID : BEGIN STRING source , target , val ; StrAssign ( source , "temp1" ) ; StrAssign ( target , "temp2" ) ; StrAssign ( val , "temp3" ) ; mmix_sets ( source , addr_offset OF stack [ left_symbol ] ) ; mmix_sets ( target , addr_offset OF stack [ target_symbol ] ) ; fprintf ( "1H\tLDB %s,fp,%s\n" , val , source ) ; fprintf ( "\tSTB %s,fp,%s\n" , val , target ) ; fprintf ( "\tADD %s,%s,1\n" , source , source ) ; fprintf ( "\tADD %s,%s,1\n" , target , target ) ; fprintf ( "\tPBNZ %s,1B\n" , val ) ; mmix_sets ( source , addr_offset OF stack [ right_symbol ] ) ; fprintf ( "\tSUBU %s,%s,1\n" , target , target ) ; fprintf ( "1H\tLDB %s,fp,%s\n" , val , source ) ; fprintf ( "\tSTB %s,fp,%s\n" , val , target ) ; fprintf ( "\tADD %s,%s,1\n" , source , source ) ; fprintf ( "\tADD %s,%s,1\n" , target , target ) ; fprintf ( "\tPBNZ %s,1B\n" , val ) ; fprintf ( "\tSTB %s,fp,%s\n" , val , target ) ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94: * other instruction mmix_strappend 94: ; PROC mmix_fix8c = Stack frame produced ( STRING opcode , CHAR c , STRING x , STRING y , INT z ) VOID : BEGIN IF z > max_byte THEN mmix_sets ( "temp10" , z ) ; fprintf ( "\t%s%c %s,%s,temp10\n" , opcode , c , x , y ) ; ELSE fprintf ( "\t%s%c %s,%s,%i\n" , opcode , c , x , y , z ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35: * other instruction mmix_fix8c 35: ; PROC mmix_loadaddr = Stack frame produced ( REF STRING outreg , STRING inreg , INT source ) VOID : BEGIN STRING bp ; StrAssign ( outreg , inreg ) ; IF storage_type OF stack [ source ] = storage_constant THEN fprintf ( "\tGETA %s,STRINGS\n" , outreg ) ; mmix_addssi ( outreg , outreg , addr_offset OF stack [ source ] ) ; ELIF storage_type OF stack [ source ] = storage_stackframe THEN get_bp ( source , bp ) ; mmix_addssi ( outreg , bp , addr_offset OF stack [ source ] ) ; ELIF storage_type OF stack [ source ] = storage_regaddr THEN fprintf ( "\tSET %s,$%i\n" , outreg , reg OF stack [ source ] ) ; ELSE error ( "mmix_loadaddr: storage type should be or !" ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62: * other instruction mmix_loadaddr 62: ; PROC mmix_strcmp = Stack frame produced ( STRING opcode , INT result , INT lsymbol , INT rsymbol ) VOID : BEGIN STRING lreg , rreg , val1 , val2 , ireg ; StrAssign ( val1 , "temp3" ) ; StrAssign ( val2 , "temp4" ) ; StrAssign ( ireg , "temp5" ) ; fprintf ( "\tSETL %s,0\n" , ireg ) ; mmix_loadaddr ( lreg , "temp1" , lsymbol ) ; mmix_loadaddr ( rreg , "temp2" , rsymbol ) ; fprintf ( "1H\tLDBU %s,%s,%s\n" , val1 , lreg , ireg ) ; fprintf ( "\tLDBU %s,%s,%s\n" , val2 , rreg , ireg ) ; fprintf ( "\tCMP %s,%s,%s\n" , val2 , val1 , val2 ) ; fprintf ( "\tBNZ %s,2F\n" , val2 ) ; fprintf ( "\tBZ %s,2F\n" , val1 ) ; fprintf ( "\tADD %s,%s,1\n" , ireg , ireg ) ; fprintf ( "\tJMP 1B\n" ) ; fprintf ( "2H\t%s $%i,%s,1\n" , opcode , reg OF stack [ result ] , val2 ) ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75: * other instruction mmix_strcmp 75: ; PROC mmix_retcopy = Stack frame produced ( INT target_symbol , INT retreg ) VOID : BEGIN STRING target , val , n ; CHAR code := get_storage_code ( target_symbol ) ; StrAssign ( target , "temp1" ) ; StrAssign ( val , "temp2" ) ; StrAssign ( n , "temp3" ) ; mmix_sets ( n , mode_size OF stack [ target_symbol ] ) ; mmix_loadaddr ( target , "temp4" , target_symbol ) ; fprintf ( "1H\tLD%c %s,$%i,0\n" , code , val , retreg ) ; fprintf ( "\tST%c %s,%s,0\n" , code , val , target ) ; fprintf ( "\tADD $%i,$%i,1\n" , retreg , retreg ) ; fprintf ( "\tADD %s,%s,1\n" , target , target ) ; fprintf ( "\tSUB %s,%s,1\n" , n , n ) ; fprintf ( "\tPBNZ %s,1B\n" , n ) ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64: * other instruction mmix_retcopy 64: ; PROC mmix_memcopy = Stack frame produced ( INT source_symbol , INT target_symbol ) VOID : BEGIN STRING sreg , treg , ireg , val , size ; INT i , n ; STRING s ; CHAR code := get_storage_code ( source_symbol ) ; IF source_symbol /= target_symbol THEN StrAssign ( val , "temp3" ) ; StrAssign ( size , "temp4" ) ; StrAssign ( ireg , "temp5" ) ; fprintf ( "\tSETL %s,%i\n" , size , mode_size OF stack [ source_symbol ] ) ; IF is_mode_array ( source_symbol ) THEN fprintf ( "\tNEGU %s,0,8\n" , ireg ) ; ELSE fprintf ( "\tSETL %s,0\n" , ireg ) ; FI ; mmix_loadaddr ( sreg , "temp1" , source_symbol ) ; mmix_loadaddr ( treg , "temp2" , target_symbol ) ; fprintf ( "1H\tLDOU %s,%s,%s\n" , val , sreg , ireg ) ; fprintf ( "\tSTOU %s,%s,%s\n" , val , treg , ireg ) ; fprintf ( "\tBZ %s,2F\n" , val ) ; fprintf ( "\tADD %s,%s,8\n" , ireg , ireg ) ; fprintf ( "\tSUB %s,%s,8\n" , size , size ) ; fprintf ( "\tPBNZ %s,1B\n" , size ) ; fprintf ( "2H\tSET $255,$255\n" ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89: * other instruction mmix_memcopy 89: ; PROC mmix_loadref = Stack frame produced ( STRING reg , INT source ) VOID : BEGIN IF storage_type OF stack [ source ] /= storage_regaddr THEN error ( "mmix_loadref: source must be stored as !" ) ; FI ; fprintf ( "\tLD%c %s,$%i,0\n" , get_storage_code ( source ) , reg , reg OF stack [ source ] ) ; storage_type OF stack [ source ] := storage_register ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32: * other instruction mmix_loadref 32: ; PROC mmix_loadsource = Stack frame produced ( REF STRING outreg , STRING inreg , INT source ) VOID : BEGIN STRING bp ; StrAssign ( outreg , inreg ) ; IF storage_type OF stack [ source ] = storage_register THEN fprintf ( "\tSET %s,$%i\n" , outreg , reg OF stack [ source ] ) ; ELIF storage_type OF stack [ source ] = storage_constant THEN IF StrEqual ( mode OF stack [ source ] , "CHAR" ) THEN fprintf ( "\tSETL %s,%i\n" , outreg , ABS ( value OF stack [ source ] ) [ 0 ] ) ; ELIF StrEqual ( mode OF stack [ source ] , "BOOL" ) THEN IF StrEqual ( value OF stack [ source ] , "FALSE" ) THEN fprintf ( "\tSETL %s,0\n" , outreg ) ; ELSE fprintf ( "\tSETL %s,1\n" , outreg ) ; FI ; ELSE mmix_sets ( outreg , str2int ( value OF stack [ source ] ) ) ; FI ; ELIF storage_type OF stack [ source ] = storage_stackframe THEN get_bp ( source , bp ) ; mmix_fix8c ( "LD" , get_storage_code ( source ) , outreg , bp , addr_offset OF stack [ source ] ) ; ELIF storage_type OF stack [ source ] = storage_regaddr THEN mmix_loadref ( outreg , source ) ; ELSE error ( "mmix_loadsource: unexpected storage type!" ) ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115: * other instruction mmix_loadsource 115: ; PROC mmix_alias = Stack frame produced ( INT target , INT source ) VOID : BEGIN STRING reg ; IF NOT is_mode_void ( target ) AND NOT is_mode_void ( source ) THEN IF storage_type OF stack [ source ] = storage_regaddr THEN fprintf ( "\tSET $%i,$%i\n" , reg OF stack [ target ] , reg OF stack [ source ] ) ; storage_type OF stack [ target ] := storage_regaddr ; ELIF storage_type OF stack [ source ] = storage_register THEN fprintf ( "\tSET $%i,$%i\n" , reg OF stack [ target ] , reg OF stack [ source ] ) ; storage_type OF stack [ target ] := storage_register ; ELIF storage_type OF stack [ source ] = storage_stackframe THEN mmix_loadaddr ( reg , "temp1" , source ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ target ] , reg ) ; storage_type OF stack [ target ] := storage_regaddr ; ELIF storage_type OF stack [ source ] = storage_constant THEN mmix_loadsource ( reg , "temp1" , source ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ target ] , reg ) ; storage_type OF stack [ target ] := storage_register ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96: * other instruction mmix_alias 96: ; PROC mmix_store = Stack frame produced ( INT target , INT source ) VOID : BEGIN STRING reg , bp ; INT val ; IF is_mode_composite ( source ) THEN mmix_memcopy ( source , target ) ; ELIF NOT is_mode_void ( target ) THEN mmix_loadsource ( reg , "temp1" , source ) ; IF storage_type OF stack [ target ] = storage_regaddr THEN fprintf ( "\tST%c %s,$%i,0\n" , get_storage_code ( target ) , reg , reg OF stack [ target ] ) ; ELIF storage_type OF stack [ target ] = storage_register THEN fprintf ( "\tSET $%i,%s\n" , reg OF stack [ target ] , reg ) ; ELIF storage_type OF stack [ target ] = storage_stackframe THEN get_bp ( target , bp ) ; mmix_fix8c ( "ST" , get_storage_code ( target ) , reg , bp , addr_offset OF stack [ target ] ) ; ELSE printf ( "source %s (%s), target %s (%s,%i)\n" , name OF stack [ source ] , mode OF stack [ source ] , name OF stack [ target ] , mode OF stack [ target ] , storage_type OF stack [ target ] ) ; error ( "Code generation 'mmix_store': invalid storage type!" ) ; FI ; FI ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99: * other instruction mmix_store 99: ; PROC generate_code = Stack frame produced VOID : BEGIN INT ptr , lptr , rptr ; STRING opcode , lreg , rreg , resreg , bp ; INT index , quadptr ; INT reg ; INT proc_info ; INT val ; INT n ; quadptr := quadptr OF table_proc_info [ current_proc ] ; process_frame ; index := quadptr ; WHILE index < quad_index DO ptr := result OF quads [ index ] ; lptr := left OF quads [ index ] ; rptr := right OF quads [ index ] ; IF code_comments THEN IF ( index > quadptr AND type OF quads [ index - 1 ] /= quad_label ) OR ( index = quadptr ) THEN fprintf ( "\n\t%% " ) ; print_quad ( index ) ; approx_code_lines := approx_code_lines + 10 ; IF approx_code_lines > 60000 THEN fprintf ( "\n#\t1 \"foo.mms\"\n\n" ) ; approx_code_lines := 0 ; FI ; FI ; FI ; IF type OF quads [ index ] = quad_addstr THEN mmix_strappend ( ptr , lptr , rptr ) ; ELIF type OF quads [ index ] = tk_MOD THEN mmix_loadsource ( lreg , "temp1" , lptr ) ; mmix_loadsource ( rreg , "temp2" , rptr ) ; fprintf ( "\tDIV $%i,%s,%s\n" , reg OF stack [ ptr ] , lreg , rreg ) ; fprintf ( "\tGET $%i,rR\n" , reg OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = ABS + OR type OF quads [ index ] = ABS - OR type OF quads [ index ] = ABS / OR type OF quads [ index ] = ABS * OR type OF quads [ index ] = tk_OR OR type OF quads [ index ] = tk_AND THEN IF type OF quads [ index ] = ABS + THEN StrAssign ( opcode , "ADD" ) ; ELIF type OF quads [ index ] = ABS - THEN StrAssign ( opcode , "SUB" ) ; ELIF type OF quads [ index ] = ABS * THEN StrAssign ( opcode , "MUL" ) ; ELIF type OF quads [ index ] = ABS / THEN StrAssign ( opcode , "DIV" ) ; ELIF type OF quads [ index ] = tk_OR THEN StrAssign ( opcode , "OR" ) ; ELIF type OF quads [ index ] = tk_AND THEN StrAssign ( opcode , "AND" ) ; FI ; mmix_loadsource ( lreg , "temp1" , lptr ) ; mmix_loadsource ( rreg , "temp2" , rptr ) ; fprintf ( "\t%s $%i,%s,%s\n" , opcode , reg OF stack [ ptr ] , lreg , rreg ) ; ELIF type OF quads [ index ] = quad_upb THEN mmix_loadaddr ( lreg , "temp1" , lptr ) ; fprintf ( "\tSUB $%i,%s,4\n" , reg OF stack [ ptr ] , lreg ) ; fprintf ( "\tLDT $%i,$%i,0\n" , reg OF stack [ ptr ] , reg OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_subscript THEN mmix_loadsource ( rreg , "temp1" , rptr ) ; mmix_loadaddr ( lreg , "temp2" , lptr ) ; n := calc_mode_size ( mode OF stack [ ptr ] , TRUE ) ; IF n = 1 THEN fprintf ( "\tADDU $%i,%s,%s\n" , reg OF stack [ ptr ] , lreg , rreg ) ; ELIF n = 2 OR n = 4 OR n = 8 OR n = 16 THEN fprintf ( "\t%iADDU $%i,%s,%s\n" , n , reg OF stack [ ptr ] , rreg , lreg ) ; ELSE mmix_sets ( "temp3" , n ) ; fprintf ( "\tMULU $%i,%s,temp3\n" , reg OF stack [ ptr ] , rreg ) ; fprintf ( "\tADDU $%i,%s,$%i\n" , reg OF stack [ ptr ] , lreg , reg OF stack [ ptr ] ) ; FI ; storage_type OF stack [ ptr ] := storage_regaddr ; ELIF type OF quads [ index ] = quad_of THEN mmix_loadaddr ( rreg , "temp1" , rptr ) ; int2str ( reg OF stack [ ptr ] , resreg ) ; StrAppend ( resreg , "$" , resreg ) ; mmix_addssi ( resreg , rreg , addr_offset OF stack [ ptr ] ) ; storage_type OF stack [ ptr ] := storage_regaddr ; ELIF type OF quads [ index ] = tk_ASSIGN THEN mmix_store ( ptr , rptr ) ; ELIF type OF quads [ index ] = quad_alias THEN mmix_alias ( ptr , lptr ) ; ELIF type OF quads [ index ] = ABS > OR type OF quads [ index ] = tk_GEQ OR type OF quads [ index ] = ABS < OR type OF quads [ index ] = tk_LEQ OR type OF quads [ index ] = ABS = OR type OF quads [ index ] = tk_NEQ THEN IF type OF quads [ index ] = ABS > THEN StrAssign ( opcode , "ZSP" ) ; ELIF type OF quads [ index ] = ABS < THEN StrAssign ( opcode , "ZSN" ) ; ELIF type OF quads [ index ] = ABS = THEN StrAssign ( opcode , "ZSZ" ) ; ELIF type OF quads [ index ] = tk_GEQ THEN StrAssign ( opcode , "ZSNN" ) ; ELIF type OF quads [ index ] = tk_LEQ THEN StrAssign ( opcode , "ZSNP" ) ; ELIF type OF quads [ index ] = tk_NEQ THEN StrAssign ( opcode , "ZSNZ" ) ; FI ; IF check_mode ( lptr , "STRING" ) THEN mmix_strcmp ( opcode , ptr , lptr , rptr ) ; ELSE mmix_loadsource ( lreg , "temp1" , lptr ) ; mmix_loadsource ( rreg , "temp2" , rptr ) ; fprintf ( "\tSUB $%i,%s,%s\n" , reg OF stack [ ptr ] , lreg , rreg ) ; fprintf ( "\t%s $%i,$%i,1\n" , opcode , reg OF stack [ ptr ] , reg OF stack [ ptr ] ) ; FI ; ELIF type OF quads [ index ] = tk_NOT THEN mmix_loadsource ( lreg , "temp1" , lptr ) ; fprintf ( "\tNEGU $%i,1,%s\n" , reg OF stack [ ptr ] , lreg ) ; ELIF type OF quads [ index ] = quad_neg THEN mmix_loadsource ( lreg , "temp1" , lptr ) ; fprintf ( "\tNEG $%i,0,%s\n" , reg OF stack [ ptr ] , lreg ) ; ELIF type OF quads [ index ] = quad_test THEN mmix_loadsource ( lreg , "temp1" , lptr ) ; fprintf ( "\tBZ %s,%s\n" , lreg , name OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_jump THEN fprintf ( "\tJMP %s\n" , name OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_printn THEN fprintf ( "\tLDA $255,Printn\n" ) ; fprintf ( "\tTRAP 0,Fputs,StdOut\n" ) ; ELIF type OF quads [ index ] = quad_printc THEN mmix_loadsource ( resreg , "temp1" , ptr ) ; fprintf ( "\tLDA $255,Buffer\n" ) ; fprintf ( "\tSTBU %s,$255,0\n" , resreg ) ; fprintf ( "\tLDA $255,BufArg\n" ) ; fprintf ( "\tTRAP 0,Fwrite,StdOut\n" ) ; ELIF type OF quads [ index ] = quad_prints THEN mmix_loadaddr ( resreg , "$255" , ptr ) ; IF NOT StrEqual ( resreg , "$255" ) THEN fprintf ( "\tSET $255,%s\n" , resreg ) ; FI ; fprintf ( "\tTRAP 0,Fputs,StdOut\n" ) ; ELIF type OF quads [ index ] = quad_open THEN val := str2int ( value OF stack [ lptr ] ) ; IF val > max_files THEN error ( "Too many files!" ) ; FI ; fprintf ( "\tSETL temp2,%i\n" , val - 1 ) ; fprintf ( "\tLDA temp1,FArg0\n" ) ; fprintf ( "\t16ADDU temp1,temp2,temp1\n" ) ; mmix_loadaddr ( rreg , "temp3" , rptr ) ; fprintf ( "\tSTOU %s,temp1,0\n" , rreg ) ; fprintf ( "\tSETL temp3,TextRead\n" ) ; fprintf ( "\tSTO temp3,temp1,8\n" ) ; fprintf ( "\tLDA $255,temp1\n" ) ; fprintf ( "\tTRAP 0,Fopen,%i\n" , val + 2 ) ; fprintf ( "\tSET $%i,$255\n" , reg OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_establish THEN val := str2int ( value OF stack [ lptr ] ) ; IF val > max_files THEN error ( "Too many files!" ) ; FI ; fprintf ( "\tSETL temp2,%i\n" , val - 1 ) ; fprintf ( "\tLDA temp1,FArg0\n" ) ; fprintf ( "\t16ADDU temp1,temp2,temp1\n" ) ; mmix_loadaddr ( rreg , "temp3" , rptr ) ; fprintf ( "\tSTOU %s,temp1,0\n" , rreg ) ; fprintf ( "\tSETL temp3,TextWrite\n" ) ; fprintf ( "\tSTO temp3,temp1,8\n" ) ; fprintf ( "\tLDA $255,temp1\n" ) ; fprintf ( "\tTRAP 0,Fopen,%i\n" , val + 2 ) ; fprintf ( "\tSET $%i,$255\n" , reg OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_close THEN val := str2int ( value OF stack [ lptr ] ) ; fprintf ( "\tTRAP 0,Fclose,%i\n" , val + 2 ) ; fprintf ( "\tSET $%i,$255\n" , reg OF stack [ ptr ] ) ; ELIF type OF quads [ index ] = quad_readc THEN val := str2int ( value OF stack [ lptr ] ) ; fprintf ( "\tSETL temp1,%i\n" , val - 1 ) ; fprintf ( "\tLDA temp2,FArg1\n" ) ; fprintf ( "\t16ADDU temp2,temp1,temp2\n" ) ; fprintf ( "\tSET $255,temp2\n" ) ; fprintf ( "\tTRAP 0,Fread,%i\n" , val + 2 ) ; fprintf ( "\tLDA temp3,FBuffer\n" ) ; fprintf ( "\tLDBU $%i,temp3,temp1\n" , reg OF stack [ ptr ] ) ; fprintf ( "\tCSN $%i,$255,0\n" , reg OF stack [ ptr ] ) ; storage_type OF stack [ ptr ] := storage_register ; ELIF type OF quads [ index ] = quad_readchar THEN fprintf ( "\tLDA $255,BufArg\n" ) ; fprintf ( "\tTRAP 0,Fread,StdIn\n" ) ; fprintf ( "\tLDA temp1,Buffer\n" ) ; fprintf ( "\tLDBU $%i,temp1,0\n" , reg OF stack [ ptr ] ) ; storage_type OF stack [ ptr ] := storage_register ; ELIF type OF quads [ index ] = quad_arg THEN IF id OF stack [ ptr ] = 0 THEN reset_args ; FI ; IF is_mode_ref ( ptr ) THEN reg OF stack [ ptr ] := get_arg_reg ; mmix_loadaddr ( lreg , "temp1" , lptr ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ ptr ] , lreg ) ; ELIF is_mode_composite ( ptr ) THEN IF code_refs THEN reg OF stack [ ptr ] := get_arg_reg ; mmix_loadaddr ( lreg , "temp1" , lptr ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ ptr ] , lreg ) ; ELSE reg OF stack [ ptr ] := get_arg_reg ; IF is_mode_array ( ptr ) THEN fprintf ( "\tSET $%i,sp\n" , reg OF stack [ ptr ] ) ; fprintf ( "\tADD $%i,$%i,8\n" , reg OF stack [ ptr ] , reg OF stack [ ptr ] ) ; mmix_loadaddr ( lreg , "temp1" , lptr ) ; fprintf ( "\tSUB temp1,temp1,8\n" ) ; fprintf ( "\tLDT temp1,temp1,0\n" ) ; fprintf ( "\tSL temp1,temp1,3\n" ) ; fprintf ( "\tADD sp,sp,temp1\n" ) ; mmix_memcopy ( lptr , ptr ) ; ELSE mmix_memcopy ( lptr , ptr ) ; mmix_loadaddr ( resreg , "temp1" , ptr ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ ptr ] , resreg ) ; FI ; FI ; ELSE reg OF stack [ ptr ] := get_arg_reg ; IF reg OF stack [ ptr ] /= reg OF stack [ lptr ] THEN mmix_loadsource ( lreg , "temp1" , lptr ) ; fprintf ( "\tSET $%i,%s\n" , reg OF stack [ ptr ] , lreg ) ; ELSE fprintf ( "\tSET temp1,temp1\n" ) ; FI ; FI ; ELIF type OF quads [ index ] = quad_argref THEN IF is_mode_composite ( lptr ) THEN mmix_loadaddr ( lreg , "temp1" , lptr ) ; fprintf ( "\tSTOU %s,sp,%i\n" , lreg , ptr - 8 ) ; ELSE mmix_loadsource ( lreg , "temp1" , lptr ) ; fprintf ( "\tSTOU %s,sp,%i\n" , lreg , ptr - 8 ) ; FI ; ELIF type OF quads [ index ] = quad_argsize THEN fprintf ( "\tSET temp1,%i\n" , ptr + 8 ) ; fprintf ( "\tSTOU temp1,sp,%i\n" , ptr ) ; fprintf ( "\tADD sp,sp,%i\n" , ptr + 8 ) ; ELIF type OF quads [ index ] = quad_alloc THEN mmix_sets ( "temp1" , ( mode_size OF stack [ ptr ] ) / 8 ) ; mmix_sets ( "temp2" , addr_offset OF stack [ ptr ] - 8 ) ; fprintf ( "\tSTT temp1,fp,temp2\n" ) ; mmix_sets ( "temp1" , calc_mode_items ( mode OF stack [ ptr ] ) ) ; mmix_sets ( "temp2" , addr_offset OF stack [ ptr ] - 4 ) ; fprintf ( "\tSTT temp1,fp,temp2\n" ) ; ELIF type OF quads [ index ] = quad_proc THEN IF current_nesting /= nesting OF stack [ ptr ] THEN error ( "Unexpected nesting disgreement!" ) FI ; proc_info := proc_info OF stack [ ptr ] ; fprintf ( "\n%s" , label OF table_proc_info [ proc_info ] ) ; fprintf ( "\tGET $%i,rJ\n" , retaddr_reg OF stack_frame ) ; fprintf ( "\tSET $%i,disp%i\n" , display_reg OF stack_frame , current_nesting ) ; fprintf ( "\tSET $%i,fp\n" , frameptr_reg OF stack_frame ) ; fprintf ( "\tSET fp,sp\n" ) ; mmix_addssi ( "sp" , "sp" , localvar_size OF stack_frame ) ; fprintf ( "\tSET disp%i,fp\n" , current_nesting ) ; ELIF type OF quads [ index ] = quad_ret THEN IF NOT is_mode_void ( ptr ) THEN IF storage_type OF stack [ ptr ] = storage_register THEN fprintf ( "\tSET $0,$%i\n" , reg OF stack [ ptr ] ) ; ELIF storage_type OF stack [ ptr ] = storage_stackframe THEN IF is_mode_composite ( ptr ) THEN mmix_loadaddr ( lreg , "$0" , ptr ) ; ELSE mmix_loadsource ( lreg , "$0" , ptr ) ; FI ; ELIF storage_type OF stack [ ptr ] = storage_regaddr THEN mmix_loadaddr ( lreg , "$0" , ptr ) ; fprintf ( "\tSET $0,$%i\n" , lreg ) ; ELSE error ( "Generate code: unhandled storage type for return value!" ) ; FI ; fprintf ( "\tSET sp,fp\n" ) ; fprintf ( "\tSET fp,$%i\n" , frameptr_reg OF stack_frame ) ; fprintf ( "\tSET disp%i,$%i\n" , current_nesting , display_reg OF stack_frame ) ; fprintf ( "\tPUT rJ,$%i\n" , retaddr_reg OF stack_frame ) ; fprintf ( "\tPOP 1,0\n" ) ; ELSE fprintf ( "\tSET sp,fp\n" ) ; fprintf ( "\tSET fp,$%i\n" , frameptr_reg OF stack_frame ) ; fprintf ( "\tSET disp%i,$%i\n" , current_nesting , display_reg OF stack_frame ) ; fprintf ( "\tPUT rJ,$%i\n" , retaddr_reg OF stack_frame ) ; fprintf ( "\tPOP 0,0\n" ) ; FI ; ELIF type OF quads [ index ] = quad_call THEN proc_info := proc_info OF stack [ lptr ] ; fprintf ( "\tPUSHJ $%i,%s\n" , get_last_reg , label OF table_proc_info [ proc_info ] ) ; IF NOT is_mode_void ( ptr ) THEN IF is_mode_composite ( ptr ) OR is_mode_ref ( ptr ) THEN fprintf ( "\tSET $%i,$%i\n" , reg OF stack [ ptr ] , get_last_reg ) ; storage_type OF stack [ ptr ] := storage_regaddr ; ELSE IF type OF stack [ ptr ] /= entity_argvar THEN fprintf ( "\tSET $%i,$%i\n" , reg OF stack [ ptr ] , get_last_reg ) ; ELSE error ( "Dear parser, you should not assign a returned value directly to an argument!" ) ; FI ; FI ; FI ; ELIF type OF quads [ index ] = quad_main THEN fprintf ( "Main\tLDA sp,STACK\n" ) ; mmix_addssi ( "fp" , "sp" , param_size OF stack_frame ) ; fprintf ( "\tSET disp1,fp\n" ) ; mmix_sets ( "temp1" , param_size OF stack_frame + localvar_size OF stack_frame ) ; fprintf ( "\tADD sp,sp,temp1\n" ) ; ptr := flookup ( "argc" ) ; mmix_fix8c ( "ST" , get_storage_code ( ptr ) , "$0" , "fp" , addr_offset OF stack [ ptr ] ) ; ptr := flookup ( "argv" ) ; mmix_sets ( "temp2" , addr_offset OF stack [ ptr ] ) ; fprintf ( "1H\tSETL temp3,%i\n" , string_size ) ; fprintf ( "\tLDOU temp4,$1,0\n" ) ; fprintf ( "2H\tLDOU temp1,temp4,0\n" ) ; fprintf ( "\tSTOU temp1,fp,temp2\n" ) ; fprintf ( "\tADD temp4,temp4,8\n" ) ; fprintf ( "\tADD temp2,temp2,8\n" ) ; fprintf ( "\tSUB temp3,temp3,8\n" ) ; fprintf ( "\tPBNZ temp3,2B\n\n" ) ; fprintf ( "\tADD $1,$1,8\n" ) ; fprintf ( "\tSUB $0,$0,1\n" ) ; fprintf ( "\tPBNZ $0,1B\n\n" ) ; ELIF type OF quads [ index ] = quad_halt THEN fprintf ( "\tTRAP 0,Halt,0\n" ) ; ELIF type OF quads [ index ] = quad_dump THEN fprintf ( "\tLDA $255,Frame\n" ) ; fprintf ( "\tSTO fp,$255,0\n" ) ; mmix_sets ( "temp1" , localvar_size OF stack_frame ) ; fprintf ( "\tSTO temp1,$255,8\n" ) ; fprintf ( "\tTRAP 0,Fwrite,StdOut\n" ) ; fprintf ( "\tLDA $255,Printn\n" ) ; fprintf ( "\tTRAP 0,Fputs,StdOut\n" ) ; ELIF type OF quads [ index ] = quad_label THEN fprintf ( "%s" , name OF stack [ ptr ] ) ; ELSE printf ( "%i: * other instruction %s\n" , index , name OF stack [ ptr ] ) ; FI ; printf ( "%i:" , index ) ; index := index + 1 ; OD ; quad_index := quadptr ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240:241:242:243:244:245:246:247:248:249:250:251:252:253:254:255:256:257:258:259:260:261:262:263:264:265:266:267:268:269:270:271:272:273:274:275:276:277:278:279:280:281:282:283:284:285:286:287:288:289:290:291:292:293:294:295:296:297:298:299:300:301:302:303:304:305:306:307:308:309:310:311:312:313:314:315:316:317:318:319:320:321:322:323:324:325:326:327:328:329:330:331:332:333:334:335:336:337:338:339:340:341:342:343:344:345:346:347:348:349:350:351:352:353:354:355:356:357:358:359:360:361:362:363:364:365:366:367:368:369:370:371:372:373:374:375:376:377:378:379:380:381:382:383:384:385:386:387:388:389:390:391:392:393:394:395:396:397:398:399:400:401:402:403:404:405:406:407:408:409:410:411:412:413:414:415:416:417:418:419:420:421:422:423:424:425:426:427:428:429:430:431:432:433:434:435:436:437:438:439:440:441:442:443:444:445:446:447:448:449:450:451:452:453:454:455:456:457:458:459:460:461:462:463:464:465:466:467:468:469:470:471:472:473:474:475:476:477:478:479:480:481:482:483:484:485:486:487:488:489:490:491:492:493:494:495:496:497:498:499:500:501:502:503:504:505:506:507:508:509:510:511:512:513:514:515:516:517:518:519:520:521:522:523:524:525:526:527:528:529:530:531:532:533:534:535:536:537:538:539:540:541:542:543:544:545:546:547:548:549:550:551:552:553:554:555:556:557:558:559:560:561:562:563:564:565:566:567:568:569:570:571:572:573:574:575:576:577:578:579:580:581:582:583:584:585:586:587:588:589:590:591:592:593:594:595:596:597:598:599:600:601:602:603:604:605:606:607:608:609:610:611:612:613:614:615:616:617:618:619:620:621:622:623:624:625:626:627:628:629:630:631:632:633:634:635:636:637:638:639:640:641:642:643:644:645:646:647:648:649:650:651:652:653:654:655:656:657:658:659:660:661:662:663:664:665:666:667:668:669:670:671:672:673:674:675:676:677:678:679:680:681:682:683:684:685:686:687:688:689:690:691:692:693:694:695:696:697:698:699:700:701:702:703:704:705:706:707:708:709:710:711:712:713:714:715:716:717:718:719:720:721:722:723:724:725:726:727:728:729:730:731:732:733:734:735:736:737:738:739:740:741:742:743:744:745:746:747:748:749:750:751:752:753:754:755:756:757:758:759:760:761:762:763:764:765:766:767:768:769:770:771:772:773:774:775:776:777:778:779:780:781:782:783:784:785:786:787:788:789:790:791:792:793:794:795:796:797:798:799:800:801:802:803:804:805:806:807:808:809:810:811:812:813:814:815:816:817:818:819:820:821:822:823:824:825:826:827:828:829:830:831:832:833:834:835:836:837:838:839:840:841:842:843:844:845:846:847:848:849:850:851:852:853:854:855:856:857:858:859:860:861:862:863:864:865:866:867:868:869:870:871:872:873:874:875:876:877:878:879:880:881:882:883:884:885:886:887:888:889:890:891:892:893:894:895:896:897:898:899:900:901:902:903:904:905:906:907:908:909:910:911:912:913:914:915:916:917:918:919:920:921:922:923:924:925:926:927:928:929:930:931:932:933:934:935:936:937:938:939:940:941:942:943:944:945:946:947:948:949:950:951:952:953:954:955:956:957:958:959:960:961:962:963:964:965:966:967:968:969:970:971:972:973:974:975:976:977:978:979:980:981:982:983:984:985:986:987:988:989:990:991:992:993:994:995:996:997:998:999:1000:1001:1002:1003:1004:1005:1006:1007:1008:1009:1010:1011:1012:1013:1014:1015:1016:1017:1018:1019:1020:1021:1022:1023:1024:1025:1026:1027:1028:1029:1030:1031:1032:1033:1034:1035:1036:1037:1038:1039:1040:1041:1042:1043:1044:1045:1046:1047:1048:1049:1050:1051:1052:1053:1054:1055:1056:1057:1058:1059:1060:1061:1062:1063:1064:1065:1066:1067:1068:1069:1070:1071:1072:1073:1074:1075:1076:1077:1078:1079:1080:1081:1082:1083:1084:1085:1086:1087:1088:1089:1090:1091:1092:1093:1094:1095:1096:1097:1098:1099:1100:1101:1102:1103:1104:1105:1106:1107:1108:1109:1110:1111:1112:1113:1114:1115:1116:1117:1118:1119:1120:1121:1122:1123:1124:1125:1126:1127:1128:1129:1130:1131:1132:1133:1134:1135:1136:1137:1138:1139:1140:1141:1142:1143:1144:1145:1146:1147:1148:1149:1150:1151:1152:1153:1154:1155:1156:1157:1158:1159:1160:1161:1162:1163:1164:1165:1166:1167:1168:1169:1170:1171:1172:1173:1174:1175:1176:1177:1178:1179:1180:1181:1182:1183:1184:1185:1186:1187:1188:1189:1190:1191:1192:1193:1194:1195:1196:1197:1198:1199:1200:1201:1202:1203:1204:1205:1206:1207:1208:1209:1210:1211:1212:1213:1214:1215:1216:1217:1218:1219:1220:1221:1222:1223:1224:1225:1226:1227:1228:1229:1230:1231:1232:1233:1234:1235:1236:1237:1238:1239:1240:1241:1242:1243:1244:1245:1246:1247:1248:1249:1250:1251:1252:1253:1254:1255:1256:1257:1258:1259:1260:1261:1262:1263:1264:1265:1266:1267:1268:1269:1270:1271:1272:1273:1274:1275:1276:1277:1278:1279:1280:1281:1282:1283:1284:1285:1286:1287:1288:1289:1290:1291:1292:1293:1294:1295:1296:1297:1298:1299:1300:1301:1302:1303:1304:1305:1306:1307:1308:1309:1310:1311:1312:1313:1314:1315:1316:1317:1318:1319:1320:1321:1322:1323:1324:1325:1326:1327:1328:1329:1330:1331:1332:1333:1334:1335:1336:1337:1338:1339:1340:1341:1342:1343:1344:1345:1346:1347:1348:1349:1350:1351:1352:1353:1354:1355:1356:1357:1358:1359:1360:1361:1362:1363:1364:1365:1366:1367: * other instruction generate_code 1367: ; PROC dump_stack = Stack frame produced VOID : BEGIN INT line := 0 ; INT proc_info ; INT index := stack_index - 1 ; WHILE index >= 1 DO line := line + 1 ; IF line > 23 THEN line := 0 ; printf ( "More..." ) ; readchar ; FI ; IF type OF stack [ index ] = entity_frame THEN printf ( "%i: START FRAME (nesting %i)\n" , index , nesting OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_startscope THEN printf ( "%i: START SCOPE _%s_\n" , index , name OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_endscope THEN printf ( "%i: END SCOPE _%s_\n" , index , name OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_var THEN printf ( "%i: variable '%s' of mode %s and size %i\n" , index , name OF stack [ index ] , mode OF stack [ index ] , mode_size OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_ptrvar THEN printf ( "%i: pointer '%s' of mode %s and size %i\n" , index , name OF stack [ index ] , mode OF stack [ index ] , mode_size OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_param THEN printf ( "%i: parameter '%s' of mode %s and size %i\n" , index , name OF stack [ index ] , mode OF stack [ index ] , mode_size OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_tempvar THEN printf ( "%i: temporary '%s' of mode %s and size %i\n" , index , name OF stack [ index ] , mode OF stack [ index ] , mode_size OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_argvar THEN printf ( "%i: argument '%s' of mode %s and size %i\n" , index , name OF stack [ index ] , mode OF stack [ index ] , mode_size OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_label THEN printf ( "%i: label '%s'\n" , index , name OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_proc THEN proc_info := proc_info OF stack [ index ] ; printf ( "%i: procedure '%s' of label %s and mode %s\n" , index , name OF stack [ index ] , label OF table_proc_info [ proc_info ] , mode OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_mode THEN printf ( "%i: mode '%s' is %s\n" , index , name OF stack [ index ] , mode OF stack [ index ] ) ; ELIF type OF stack [ index ] = entity_constant THEN printf ( "%i: constant '%s' OF mode %s\n" , index , name OF stack [ index ] , mode OF stack [ index ] ) ; ELSE printf ( "%i: other\n" , index ) ; error ( "Unknown symbol table entry!" ) ; FI ; index := index - 1 ; OD ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139:140:141:142:143:144:145:146:147:148:149:150:151:152:153:154:155:156:157:158:159:160:161:162:163:164:165:166:167:168:169:170:171:172:173:174:175:176:177:178:179:180:181:182:183:184:185:186:187:188:189:190:191:192:193:194:195:196:197:198:199:200:201:202:203:204:205:206:207:208:209:210:211:212:213:214:215:216:217:218:219:220:221:222:223:224:225:226:227:228:229:230:231:232:233:234:235:236:237:238:239:240: * other instruction dump_stack 240: ; PROC dump_frame = Stack frame produced VOID : BEGIN [ 4 ] STRING table_storage ; INT offset ; INT storage_type ; INT line := 2 ; INT index := stack_index - 1 ; StrAssign ( table_storage [ 0 ] , "con" ) ; StrAssign ( table_storage [ 1 ] , "reg" ) ; StrAssign ( table_storage [ 2 ] , "mem" ) ; StrAssign ( table_storage [ 3 ] , "ptr" ) ; WHILE type OF stack [ index ] /= entity_frame DO index := index - 1 OD ; printf ( "ID STO SIZE OFFSET REG NEST MODE \n" ) ; printf ( "----------------------------------------------------------------------------\n" ) ; WHILE index < stack_index DO IF type OF stack [ index ] = entity_var OR type OF stack [ index ] = entity_tempvar OR type OF stack [ index ] = entity_ptrvar OR type OF stack [ index ] = entity_argvar OR type OF stack [ index ] = entity_param THEN line := line + 1 ; IF line > 20 THEN line := 0 ; printf ( "More..." ) ; readchar ; FI ; storage_type := storage_type OF stack [ index ] ; IF type OF stack [ index ] = entity_param AND is_mode_composite ( index ) THEN offset := addr_offset OF stack [ index ] - param_size OF stack_frame ; ELSE offset := addr_offset OF stack [ index ] ; FI ; printf ( "%-20s(%3i) %-3s %8i %10i $%3i %4i %s\n" , name OF stack [ index ] , index , table_storage [ storage_type ] , mode_size OF stack [ index ] , offset , reg OF stack [ index ] , nesting OF stack [ index ] , mode OF stack [ index ] ) ; FI ; index := index + 1 ; OD ; printf ( "----------------------------------------------------------------------------\n" ) ; printf ( "FRAME SIZE = %i\n" , localvar_size OF stack_frame ) ; printf ( "----------------------------------------------------------------------------\n" ) ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122:123:124:125:126:127:128:129:130:131:132:133:134:135:136:137:138:139: * other instruction dump_frame 139: ; PROC dump_procedures = Stack frame produced VOID : BEGIN INT line := 0 ; INT index := 0 ; printf ( "LABEL QUADPTR MAXTEMP DONE \n" ) ; printf ( "--------------------------------------------\n" ) ; WHILE index <= proc_info_index DO line := line + 1 ; IF line > 20 THEN line := 0 ; printf ( "More..." ) ; readchar ; FI ; printf ( "%-10s %6i %7i %4i\n" , label OF table_proc_info [ index ] , quadptr OF table_proc_info [ index ] , max_temp OF table_proc_info [ index ] , done OF table_proc_info [ index ] ) ; index := index + 1 ; OD ; END Generating code... Stack frame produced 10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52: * other instruction dump_procedures 52: ; PROC dump_quads = Stack frame produced VOID : BEGIN INT resptr , lptr , rptr ; INT proc_info ; INT line := 0 ; INT index := 0 ; WHILE index < quad_index DO line := line + 1 ; IF line > 23 THEN line := 0 ; printf ( "More..." ) ; readchar ; FI ; resptr := result OF quads [ index ] ; lptr := left OF quads [ index ] ; rptr := right OF quads [ index ] ; printf ( "%i: " , index ) ; IF type OF quads [ index ] = tk_ASSIGN THEN printf ( "ASSIGN %s (%i) := %s (%i)\n" , name OF stack [ resptr ] , resptr , name OF stack [ rptr ] , rptr ) ; ELIF type OF quads [ index ] = quad_alias THEN printf ( "ALIAS %s (%i) -> %s (%i)\n" , name OF stack [ lptr ] , lptr , name OF stack [ resptr ] , resptr ) ; ELIF type OF quads [ index ] = quad_main THEN printf ( "MAIN\n" ) ; ELIF type OF quads [ index ] = quad_halt THEN printf ( "HALT\n" ) ; ELIF type OF quads [ index ] = quad_dump THEN printf ( "DUMPFRAME\n" ) ; ELIF type OF quads [ index ] = ABS = THEN printf ( "EQUAL %s (%i) = %s (%i) -> %s (%i)\n" , name OF stack [ lptr ] , lptr , name OF stack [ rptr ] , rptr , name OF stack [ resptr ] , resptr ) ; ELIF type OF quads [ index ] = ABS > THEN printf ( "GREATER %s (%i) > %s (%i) -> %s (%i)\n" , name OF stack [ lptr ] , lptr , name OF stack [ rptr ] , rptr , name OF stack [ resptr ] , resptr ) ; ELIF type OF quads [ index ] = ABS < THEN printf ( "LESS %s (%i) > %s (%i) -> %s (%i)\n" , name OF stack [ lptr ] , lptr , name OF stack [ rptr ] , rptr , name OF st