From 05fc94ce906a7b92a2a5a76e063337ec1cc00ad2 Mon Sep 17 00:00:00 2001 From: Stephen Casner Date: Mon, 15 Feb 2021 00:10:24 -0800 Subject: [PATCH] Extend left-shift operator - Negative shift values are right-shift - Optimize shift of 0 or more than 15 - Allow shifting symbols by complex relocation --- extree.c | 33 +++++++- tests/test-prec.lst.ok | 172 ++++++++++++++++++++--------------------- tests/test-prec.mac | 3 +- 3 files changed, 119 insertions(+), 89 deletions(-) diff --git a/extree.c b/extree.c index eca608d..a59164e 100644 --- a/extree.c +++ b/extree.c @@ -721,15 +721,44 @@ EX_TREE *evaluate( left = evaluate(tp->data.child.left, undef); right = evaluate(tp->data.child.right, undef); - /* Operate if both are literals */ if (left->type == EX_LIT && right->type == EX_LIT) { - res = new_ex_lit(left->data.lit << right->data.lit); + int shift = right->data.lit; + if (shift < 0) + res = new_ex_lit(left->data.lit >> -shift); + else + res = new_ex_lit(left->data.lit << shift); free_tree(left); free_tree(right); break; } + if (right->type == EX_LIT && /* Symbol shifted 0 == symbol */ + right->data.lit == 0) { + res = left; + free_tree(right); + break; + } + + if (right->type == EX_LIT && /* Anything shifted 16 == 0 */ + ((int)right->data.lit > 15 || + (int)right->data.lit < -15)) { + res = new_ex_lit(0); + free_tree(left); + free_tree(right); + break; + } + + if (right->type == EX_LIT) { /* Other shifts become * or / */ + int shift = right->data.lit; + if (shift > 0) + res = new_ex_bin(EX_MUL, left, new_ex_lit(1 << shift)); + else + res = new_ex_bin(EX_DIV, left, new_ex_lit(1 << -shift)); + free_tree(right); + break; + } + /* Anything else returns verbatim */ res = new_ex_bin(EX_LSH, left, right); } diff --git a/tests/test-prec.lst.ok b/tests/test-prec.lst.ok index 612ece5..a289409 100644 --- a/tests/test-prec.lst.ok +++ b/tests/test-prec.lst.ok @@ -24,104 +24,104 @@ 24 000030 001230 a: .word 123 _ 3 ; 001230 25 000032 000500 .word five _ 6 ; 000500 26 000034 004040 .word 101_five ; 004040 -test-prec.mac:27: ***ERROR Invalid expression - 27 000036 000000 .word a _ 3 ; Invalid expression - 28 - 29 000040 177401 .word - 377 ; 177401 - 30 000042 000377 .word + 377 ; 000377 - 31 - 32 000044 177400 .word ^C 377 ; 177400 - 33 000046 177400 .word ^c 377 ; 177400 - 34 000050 052525 .word ^B 0101010101010101 ; 052525 - 35 000052 125252 .word ^b 1010101010101010 ; 125252 - 36 000054 000144 .word ^d 100 ; 000144 - 37 000056 000144 .word 100. ; 000144 - 38 000060 000400 .word ^x 100 ; 000400 hexadecimal is an extension - 39 000062 070254 .word ^rRAD ; 070254 up to 3 characters; no leading spaces - 40 000064 003100 .word ^rA ; 003100 up to 3 characters - 41 000066 000050 .word ^r A ; 000050 up to 3 characters - 42 000070 000001 .word ^r A ; 000001 up to 3 characters - 43 000072 000051 .word ^r AA ; 000051 - 44 000074 003101 .word ^rA A ; 003101 - 45 000076 003150 .word ^rAA ; 003150 - 46 000100 003151 .word ^r^/AAA/ ; bracketed strings are an extension - 47 000102 070254 .word ^r ; bracketed strings are an extension - 48 000104 000054 .word ^r< AD> ; bracketed strings are an extension - 49 000106 000004 .word ^r< D> ; bracketed strings are an extension - 50 000110 070204 .word ^r ; bracketed strings are an extension - 51 000112 070250 .word ^r ; bracketed strings are an extension - 52 000114 157614 .word ^R50. ; 157614 there is no whitespace in between. - 53 000116 040300 .word ^f 1.5 ; 040300 - 54 - 55 ;;;;; - 56 ; - 57 ; Test bracketing - 58 ; - 59 000120 000007 .word 1 + < 2 * 3 > ; 1 + 6 = 7 - 60 000122 000007 .word 1 + ^! 2 * 3 ! ; 1 + 6 = 7 - 61 000124 000007 .word 1 + ^/ 2 * 3 / ; 1 + 6 = 7 - 62 000126 000007 .word 1 + ^$ 2 * 3 $ ; 1 + 6 = 7 -test-prec.mac:63: ***ERROR Invalid expression - 63 000130 000003 000000 .word 1 + ^* 2 * 3 * ; Invalid expression - 64 - 65 ;;;;; - 66 ; - 67 ; There was an obscure bug in parse_expr(), used to evaluate 'if df', - 68 ; where it could skip past the end of the line marker. - 69 ; - 70 ; If this happened inside an expanded macro, then after that was the - 71 ; next line... - 72 ; In other cases it might be worse. - 73 ; - 74 .macro dirdef name, flags, cond - 75 .rad50 /.'name/ - 76 .byte flags+0, 0 - 77 .if df cond - 78 .globl opcerr - 79 .word opcerr - 80 .iff - 81 .globl name - 82 .word name - 83 .endc - 84 .endm - 85 - 86 000134 dirdef name - 1 000134 130461 051010 .rad50 /.name/ - 2 000140 000 000 .byte +0, 0 + 27 000036 000377 .word 177400 _ -8. ; 000377 + 28 000040 000000C .word a _ 3 ; Complex relocation + 29 + 30 000042 177401 .word - 377 ; 177401 + 31 000044 000377 .word + 377 ; 000377 + 32 + 33 000046 177400 .word ^C 377 ; 177400 + 34 000050 177400 .word ^c 377 ; 177400 + 35 000052 052525 .word ^B 0101010101010101 ; 052525 + 36 000054 125252 .word ^b 1010101010101010 ; 125252 + 37 000056 000144 .word ^d 100 ; 000144 + 38 000060 000144 .word 100. ; 000144 + 39 000062 000400 .word ^x 100 ; 000400 hexadecimal is an extension + 40 000064 070254 .word ^rRAD ; 070254 up to 3 characters; no leading spaces + 41 000066 003100 .word ^rA ; 003100 up to 3 characters + 42 000070 000050 .word ^r A ; 000050 up to 3 characters + 43 000072 000001 .word ^r A ; 000001 up to 3 characters + 44 000074 000051 .word ^r AA ; 000051 + 45 000076 003101 .word ^rA A ; 003101 + 46 000100 003150 .word ^rAA ; 003150 + 47 000102 003151 .word ^r^/AAA/ ; bracketed strings are an extension + 48 000104 070254 .word ^r ; bracketed strings are an extension + 49 000106 000054 .word ^r< AD> ; bracketed strings are an extension + 50 000110 000004 .word ^r< D> ; bracketed strings are an extension + 51 000112 070204 .word ^r ; bracketed strings are an extension + 52 000114 070250 .word ^r ; bracketed strings are an extension + 53 000116 157614 .word ^R50. ; 157614 there is no whitespace in between. + 54 000120 040300 .word ^f 1.5 ; 040300 + 55 + 56 ;;;;; + 57 ; + 58 ; Test bracketing + 59 ; + 60 000122 000007 .word 1 + < 2 * 3 > ; 1 + 6 = 7 + 61 000124 000007 .word 1 + ^! 2 * 3 ! ; 1 + 6 = 7 + 62 000126 000007 .word 1 + ^/ 2 * 3 / ; 1 + 6 = 7 + 63 000130 000007 .word 1 + ^$ 2 * 3 $ ; 1 + 6 = 7 +test-prec.mac:64: ***ERROR Invalid expression + 64 000132 000003 000000 .word 1 + ^* 2 * 3 * ; Invalid expression + 65 + 66 ;;;;; + 67 ; + 68 ; There was an obscure bug in parse_expr(), used to evaluate 'if df', + 69 ; where it could skip past the end of the line marker. + 70 ; + 71 ; If this happened inside an expanded macro, then after that was the + 72 ; next line... + 73 ; In other cases it might be worse. + 74 ; + 75 .macro dirdef name, flags, cond + 76 .rad50 /.'name/ + 77 .byte flags+0, 0 + 78 .if df cond + 79 .globl opcerr + 80 .word opcerr + 81 .iff + 82 .globl name + 83 .word name + 84 .endc + 85 .endm + 86 + 87 000136 dirdef name + 1 000136 130461 051010 .rad50 /.name/ + 2 000142 000 000 .byte +0, 0 3 .if df 4 .globl opcerr 5 .word opcerr 6 .iff 7 .globl name - 8 000142 000000G .word name + 8 000144 000000G .word name 9 .endc - 87 -test-prec.mac:88: ***ERROR Invalid expression in .WORD - 88 .word ( + 88 test-prec.mac:89: ***ERROR Invalid expression in .WORD - 89 ( - 90 -test-prec.mac:91: ***ERROR Invalid expression in .WORD - 91 .word _,$ + 89 .word ( +test-prec.mac:90: ***ERROR Invalid expression in .WORD + 90 ( + 91 test-prec.mac:92: ***ERROR Invalid expression in .WORD - 92 _ - 93 000144 000000G $ -test-prec.mac:94: ***ERROR Invalid expression in .WORD - 94 .word / + 92 .word _,$ +test-prec.mac:93: ***ERROR Invalid expression in .WORD + 93 _ + 94 000146 000000G $ test-prec.mac:95: ***ERROR Invalid expression in .WORD - 95 / + 95 .word / test-prec.mac:96: ***ERROR Invalid expression in .WORD - 96 .word ^px + 96 / test-prec.mac:97: ***ERROR Invalid expression in .WORD - 97 ^px + 97 .word ^px test-prec.mac:98: ***ERROR Invalid expression in .WORD - 98 .word ^px / 256 + 98 ^px test-prec.mac:99: ***ERROR Invalid expression in .WORD - 99 ^px / 256 - 100 - 101 000146 000001 000002 000003 1,2,3 - 102 000154 000000G 000000G 000000G .1,.2,.3 - 102 + 99 .word ^px / 256 +test-prec.mac:100: ***ERROR Invalid expression in .WORD + 100 ^px / 256 + 101 + 102 000150 000001 000002 000003 1,2,3 + 103 000156 000000G 000000G 000000G .1,.2,.3 + 103 Symbol table @@ -133,4 +133,4 @@ $ = ****** GX .1 = ****** GX .3 = ****** GX FIVE Program sections: . ABS. 000000 000 (RW,I,GBL,ABS,OVR,NOSAV) - 000162 001 (RW,I,LCL,REL,CON,NOSAV) + 000164 001 (RW,I,LCL,REL,CON,NOSAV) diff --git a/tests/test-prec.mac b/tests/test-prec.mac index 6ef75ea..5ad7462 100644 --- a/tests/test-prec.mac +++ b/tests/test-prec.mac @@ -24,7 +24,8 @@ five = 5 a: .word 123 _ 3 ; 001230 .word five _ 6 ; 000500 .word 101_five ; 004040 - .word a _ 3 ; Invalid expression + .word 177400 _ -8. ; 000377 + .word a _ 3 ; Complex relocation .word - 377 ; 177401 .word + 377 ; 000377