Mercurial > hg > Members > kono > compiler-examples
changeset 24:aecd80408312
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 26 Oct 2022 17:37:18 +0900 |
parents | 8c4683873ec8 |
children | e84ea6c0d359 |
files | calc64.c s-code-arm-mac.c |
diffstat | 2 files changed, 357 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calc64.c Wed Oct 26 17:37:18 2022 +0900 @@ -0,0 +1,318 @@ +/* + Simple Calculator + $Id$ + */ + +#include <stdio.h> + +char *ptr,*last_ptr; +long value,lvalue; +long last_token; +long variable[48]; + +static long expr(); +static long aexpr(); +static long mexpr(); +static long term(); + + +#define T_EQUAL (0x100|'=') +#define T_NEQUAL (0x100|'!') +#define T_LSHIFT (0x100|'<') +#define T_RSHIFT (0x100|'>') + +static void +line_skip() +{ + while(*ptr++); + last_ptr = ptr; + last_token = EOF; +} + +static void +error(description) +char *description; +{ + fprintf(stderr,"%s on %s\n",description,last_ptr); + line_skip(); +} + +static long +token() +{ + long c,d; + + last_ptr = ptr; /* for error position */ + c= *ptr; + while(c<=' ' && c) { + c = *++ptr; + } + if(!c) { + last_token = EOF; + return last_token; + } + ptr++; + if ('/'==c && ('/'== *ptr || '*'== *ptr)) { /* comment */ + line_skip(); + return EOF; + } + if('1'<=c && c<='9') { /* Decimal */ + d = c-'0'; + while((c= *ptr++)) { + if('0'<=c && c<='9') { + d = d*10 + (c - '0'); + } else { + break; + } + } + c && ptr--; + value = d; + last_token = '0'; + return last_token; + } else if ('0'==c && 'x'== *ptr) { /* Hex */ + ptr++; + d = 0; + while((c= *ptr++)) { + if('0'<=c && c<='9') { + d = d*16 + (c - '0'); + } else if('a'<=c && c<='f') { + d = d*16 + (c - 'a' + 10); + } else if('A'<=c && c<='F') { + d = d*16 + (c - 'a' + 10); + } else { + break; + } + } + c && ptr--; + value = d; + last_token = '0'; + return last_token; + } else if ('0'==c) { /* Octal */ + d = c-'0'; + while((c= *ptr++)) { + if('0'<=c && c<='7') { + d = d*8 + (c - '0'); + } else { + break; + } + } + c && ptr--; + value = d; + last_token = '0'; + return last_token; + } else if ('\''==c) { /* Ascii */ + d = 0; + while((c= *ptr++)) { + if('\''!=c && c<=0x7f) { + d = d*256 + c; + } else if(c>=0x80 && *ptr) { + d = d*256*256 + c*256 + *ptr++; + } else { + break; + } + } + c && ptr--; + value = d; + last_token = '0'; + return last_token; + } else if (('a'<=c && c<='z') || /* variable */ + ('A'<=c && c<='Z')) { + value = ((c>'Z')?c-'a'+'Z'-'A'+1:c-'A'); + last_token = 'v'; + return last_token; + } else if ('='==c && '='== *ptr) { /* equal */ + ptr++; + last_token = T_EQUAL; + return last_token; + } else if ('!'==c && '='== *ptr) { /* equal */ + ptr++; + last_token = T_NEQUAL; + return last_token; + } else if ('<'==c && '<'== *ptr) { /* shift */ + ptr++; + last_token = T_LSHIFT; + return last_token; + } else if ('>'==c && '>'== *ptr) { /* shift */ + ptr++; + last_token = T_RSHIFT; + return last_token; + } else { + last_token = c; + return last_token; + } +} + +static long +expr() +{ + long d,assign; + + d = aexpr(); + assign = lvalue; + while(last_token!=EOF) { + switch(last_token) { + case '<': + d = (d < aexpr()); + break; + case '>': + d = (d > aexpr()); + break; + case T_EQUAL: + d = (d == aexpr()); + break; + case T_NEQUAL: + d = (d != aexpr()); + break; + case T_LSHIFT: + d <<= aexpr(); + break; + case T_RSHIFT: + d >>= aexpr(); + break; + case '?': + { + long true; + true = expr(); + if(last_token != ':') { + error("? expression not terminated with :"); + return true; + } + if(d) { + expr(); + return true; + } else { + return expr(); + } + } + break; + case '=': + if(assign>=0) { + d = expr(); + variable[assign] = d; + return d; + } else { + error("Bad assignment"); + return 0; + } + break; + case ':': + case ')': + return d; + default: + error("Bad expression"); + token(); + } + } + last_token = EOF; + return d; +} + +static long +aexpr() +{ + long d; + + d = mexpr(); + while(last_token!=EOF) { + switch(last_token) { + case '^': + d ^= mexpr(); + break; + case '|': + d |= mexpr(); + break; + case '&': + d &= mexpr(); + break; + case '-': + d -= mexpr(); + break; + case '+': + d += mexpr(); + break; + default: + return d; + } + } + return d; +} + +static long +mexpr() +{ + long d; + + d = term(); + while(last_token!=EOF) { + switch(last_token) { + case '*': + d *= term(); + break; + case '/': + d /= term(); + break; + case '%': + d %= term(); + break; + case '^': + d ^= term(); + break; + default: + return d; + } + } + return d; +} + +static long term() +{ + long d; + + lvalue= -1; + token(); + if(last_token==EOF) { + error("Term expected"); + } + switch(last_token) { + case '0': + d = value; + token(); + return d; + case 'v': + d = lvalue = value; + token(); + return variable[d]; + case '-': + return - term(); + case '!': + return ! term(); + case '(': + d = expr(); + if(last_token != ')') { + error("Unbalanced parenthsis"); + } + token(); + return d; + default: + token(); + error("Unknown term"); + return 0; + } +} + +int +main(int ac,char *av[]) +{ + long d; + char buf[BUFSIZ]; + + while (fgets(buf,BUFSIZ,stdin)) { + ptr = buf; + d = expr(); + printf("%s = 0x%016lx = %ld\n",buf,d,d); + fflush(stdout); + } + return 0; +} + +/* end */
--- a/s-code-arm-mac.c Wed Oct 19 17:51:34 2022 +0900 +++ b/s-code-arm-mac.c Wed Oct 26 17:37:18 2022 +0900 @@ -11,6 +11,29 @@ char *intro[] = { " .section __TEXT,__text,regular,pure_instructions\n" " .build_version macos, 12, 0 sdk_version 12, 3\n" +" .globl _print ; -- Begin function print\n" +" .p2align 2\n" +"_print: ; @print\n" +" .cfi_startproc\n" +"; %bb.0:\n" +" sub sp, sp, #32\n" +" stp x29, x30, [sp, #16] ; 16-byte Folded Spill\n" +" add x29, sp, #16\n" +" .cfi_def_cfa w29, 16\n" +" .cfi_offset w30, -8\n" +" .cfi_offset w29, -16\n" +" str x0, [sp]\n" +"Lloh0:\n" +" adrp x0, l_.str@PAGE\n" +"Lloh1:\n" +" add x0, x0, l_.str@PAGEOFF\n" +" bl _printf\n" +" ldp x29, x30, [sp, #16] ; 16-byte Folded Reload\n" +" add sp, sp, #32\n" +" ret\n" +" .loh AdrpAdd Lloh0, Lloh1\n" +" .cfi_endproc\n" +"\n" " .globl _main ; -- Begin function main\n" " .p2align 2\n" " _main: ; @main\n" @@ -26,11 +49,16 @@ " .loh AdrpLdr Lloh0, Lloh1\n" " .cfi_endproc\n" " ; -- End function\n" +" .section __TEXT,__cstring,cstring_literals\n" +"l_.str: ; @.str\n" +" .asciz \"%ld\\n\"\n" " .section __DATA,__data\n" " .globl _v ; @a\n" " .p2align 3\n" " _a:\n" " .quad 64 ; 64\n" +" _v:\n" +" .quad 64*100 ; 64\n" "\n" " .subsections_via_symbols\n", NULL @@ -46,7 +74,7 @@ emit_compare() { printf("\tldr x1,[sp, 8]!\n"); - printf("\tcmp x0,x0,x1\n"); + printf("\tcmp x0,x1\n"); } void @@ -83,21 +111,17 @@ emit_calc(enum opcode op) { if(op==O_DIV ) { - printf("\tmovq %%rax,%%rbx\n"); - printf("\tpopq %%rax\n"); - printf("\tcltd\n"); - printf("\tidivq %%rbx\n"); + printf("\tldr x1,[sp , #16]! \n"); + printf("\tsdiv x0 ,x1 , x0\n"); } else if( op==O_DIV_R ) { - printf("\tpopq %%rbx\n"); - printf("\tcltd\n"); - printf("\tidivq %%rbx\n"); + printf("\tldr x1,[sp , #16]! \n"); + printf("\tsdiv x1 ,x0 , x0\n"); } else if(op==O_SUB) { - printf("\tpopq %%rbx\n"); - printf("\t%s %%rbx,%%rax\n",opcode[op]); - printf("\tnegq %%rax\n"); + printf("\tldr x1,[sp , #16]! \n"); + printf("\tsub x1 ,x0 , x0\n"); } else { - printf("\tpopq %%rbx\n"); - printf("\t%s %%rbx,%%rax\n",opcode[op]); + printf("\tldr x1,[sp , #16]! \n"); + printf("\t%s x1 ,x0 , x0\n",opcode[op]); } } @@ -105,7 +129,7 @@ emit_value(d) int d; { - printf("\tmovq $%d,%%rax\n",d); + printf("\tmov x0, #%d\n",d); // 16bit ? } void @@ -126,8 +150,7 @@ void emit_print() { - printf("\tmovq %%rax, %%rdi\n"); - printf("\tcall _print\n"); + printf("\tbl _print\n"); }