diff options
-rw-r--r-- | input/add-loop-directive.asm | 21 | ||||
-rw-r--r-- | src/package.lisp | 6 | ||||
-rw-r--r-- | src/parse.lisp | 21 | ||||
-rw-r--r-- | t/parse.lisp | 116 |
4 files changed, 123 insertions, 41 deletions
diff --git a/input/add-loop-directive.asm b/input/add-loop-directive.asm new file mode 100644 index 0000000..5bccff3 --- /dev/null +++ b/input/add-loop-directive.asm @@ -0,0 +1,21 @@ +.data + arr 1 2 3 4 + s 3 + i 0 + +.text + load $5 s + load $10 arr + load $6 i + jrl CMP +L: + add $9 $10 $6 + load $7 0($9) + load $8 1($9) + add $7 $7 $8 + + store $7 0($9) + addi $6 $6 0x1 +CMP: + cmp $6 $5 + bgt L diff --git a/src/package.lisp b/src/package.lisp index 4bdd274..115942e 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -21,8 +21,4 @@ (defpackage #:parse (:use #:cl) - (:export #:str->ast - ;; exported for testing only - #:register - #:instr - )) + (:export #:str->ast)) diff --git a/src/parse.lisp b/src/parse.lisp index 109205f..d07fbde 100644 --- a/src/parse.lisp +++ b/src/parse.lisp @@ -13,7 +13,7 @@ (:constant nil)) (esrap:defrule nl-inc (+ #\newline) - (:destructure (n) + (:lambda (n) (declare (ignore n)) (incf line-number) nil)) @@ -46,6 +46,9 @@ (:function cadr) (:lambda (e) (list 'rr e))) +(esrap:defrule var alpha + (:lambda (e) (list (list 'rr 0) (list 'var e)))) + (esrap:defrule dereference (and (esrap:? (or #\+ #\-)) int #\( register #\)) (:destructure (s i1 w1 r w2) (declare (ignore w1 w2)) @@ -107,12 +110,12 @@ DESTRUCTURE-PATTERN is the list of non-terminals on the right side of the gramma (defrule-instr i-type-3 'i (0 1 2) register register immediate) (defrule-instr j-type-3 'j (1 0) label) -(esrap:defrule i-type-1 (and i-type-1-m space register space (or dereference alpha)) +(esrap:defrule i-type-1 (and i-type-1-m space register space (or dereference var)) (:destructure (m w1 s w2 di) (declare (ignore w1 w2)) `(i ,m ,s ,@di))) -(esrap:defrule i-type-2 (and i-type-2-m space register space (or dereference alpha)) +(esrap:defrule i-type-2 (and i-type-2-m space register space (or dereference var)) (:destructure (m w1 s w2 di) (declare (ignore w1 w2)) `(i ,m ,@(util:insert-in-middle di s)))) @@ -142,8 +145,7 @@ DESTRUCTURE-PATTERN is the list of non-terminals on the right side of the gramma (esrap:defrule text (and ".TEXT" (esrap:? space) nl (* text-line)) (:function cadddr) - (:lambda (e) - `(t ,@(remove nil e)))) + (:lambda (e) `(x ,@(remove nil e)))) ;;; defines rules to parse the .data segment @@ -163,11 +165,10 @@ DESTRUCTURE-PATTERN is the list of non-terminals on the right side of the gramma (esrap:defrule data (and ".DATA" (esrap:? space) nl (* data-line)) (:function cadddr) - (:lambda (e) - (list 'd (apply #'append e)))) + (:lambda (e) `(d ,@(apply #'append e)))) ;;; defines rules to parse a program -(esrap:defrule str->ast (* (or data text)) - (:lambda (e) - (list 'p (apply #'append e)))) +(esrap:defrule str->ast (and (* (or space nl)) (* (or data text))) + (:function cadr) + (:lambda (e) `(p ,@e))) diff --git a/t/parse.lisp b/t/parse.lisp index 5b23343..9562e1d 100644 --- a/t/parse.lisp +++ b/t/parse.lisp @@ -11,53 +11,117 @@ (test esrap-register-bases (is (equal '(parse::p - (parse::t - (parse::r "ADD" (parse::rr 10) (parse::rr 10) (parse::rr 10)))) + (parse::x + (parse::r "ADD" (parse::rr 10) (parse::rr 10) (parse::rr 10)))) (esrap:parse 'parse::str->ast (format nil ".TEXT~%~tADD $0O012 $0B1010 $0XA~%"))))) (test esrap-instr-all-type-r (is (equal - '(parse::p - (parse::t - (parse::r "ADDV" (parse::rr 1) (parse::rr 2) (parse::rr 3)) - (parse::r "NOT" (parse::rr 4) (parse::rr 0) (parse::rr 5)) - (parse::r "CMP" (parse::rr 6) (parse::rr 7) (parse::rr 0)))) + '(parse::p + (parse::x + (parse::r "ADDV" (parse::rr 1) (parse::rr 2) (parse::rr 3)) + (parse::r "NOT" (parse::rr 4) (parse::rr 0) (parse::rr 5)) + (parse::r "CMP" (parse::rr 6) (parse::rr 7) (parse::rr 0)))) (esrap:parse 'parse::str->ast (format nil ".TEXT~%~tADDV $3 $1 $2 ~tNOT $5 $4~%~tCMP $6 $7~%"))))) (test esrap-instr-all-type-i (is (equal - '(parse::p - (parse::t - (parse::i "LOADV" (parse::rr 8) (parse::rr 9) (parse::imm 1)) - (parse::i "STORE" (parse::rr 3) (parse::rr 5) (parse::imm 3)) - (parse::i "ADDI" (parse::rr 5) (parse::rr 4) (parse::imm 2)))) + '(parse::p + (parse::x + (parse::i "LOADV" (parse::rr 8) (parse::rr 9) (parse::imm 1)) + (parse::i "STORE" (parse::rr 3) (parse::rr 5) (parse::imm 3)) + (parse::i "ADDI" (parse::rr 5) (parse::rr 4) (parse::imm 2)))) (esrap:parse 'parse::str->ast (format nil ".TEXT~%~tLOADV $8 1($9) ~tSTORE $5 3($3)~%~tADDI $5 $4 2~%"))))) (test esrap-instr-type-all-type-j (is (equal - '(parse::p - (parse::t - (parse::j "JMP" (parse::rr 3) (parse::imm 3)) - (parse::j "JRL" (parse::rr 0) (parse::l "FOO")) - (parse::j "PUSH" (parse::rr 5) (parse::imm 0)))) + '(parse::p + (parse::x + (parse::j "JMP" (parse::rr 3) (parse::imm 3)) + (parse::j "JRL" (parse::rr 0) (parse::l "FOO")) + (parse::j "PUSH" (parse::rr 5) (parse::imm 0)))) (esrap:parse 'parse::str->ast (format nil ".TEXT~%~tJMP 3($3) ~tJRL FOO~%~tPUSH $5~%"))))) +(test esrap-instr-type-i-vars + (is (equal + '(parse::p + (parse::x + (parse::i "LOADV" (parse::rr 8) (parse::rr 0) (parse::var "vector")) + (parse::i "STORE" (parse::rr 0) (parse::rr 5) (parse::var "int")))) + (esrap:parse 'parse::str->ast (format nil ".TEXT~%~tLOADV $8 vector +~tSTORE $5 int~%"))))) + (test esrap-instr-type-all-lazy-spaces (is (equal - '(parse::p - (parse::t - (parse::j "JMP" (parse::rr 3) (parse::imm 3)) - (parse::j "JRL" (parse::rr 0) (parse::l "FOO")) - (parse::j "PUSH" (parse::rr 5) (parse::imm 0)))) + '(parse::p + (parse::x + (parse::j "JMP" (parse::rr 3) (parse::imm 3)) + (parse::j "JRL" (parse::rr 0) (parse::l "FOO")) + (parse::j "PUSH" (parse::rr 5) (parse::imm 0)))) (esrap:parse 'parse::str->ast (format nil "~t~%.TEXT~t~%JMP 3($3)~t JRL FOO~t~%PUSH $5~%"))))) (test esrap-data-singleton (is (equal - '(parse::p - (parse::d - 1))) - (esrap:parse 'parse:str->ast (format nil ".DATA~%~tA 1~%")))) + '(parse::p + (parse::d + 1)) + (esrap:parse 'parse:str->ast (format nil ".DATA~%~tA 1~%"))))) + +(test esrap-data-loaded + (is (equal + '(parse::p + (parse::d + 1 2 3 4 5 6 7 8)) + (esrap:parse 'parse:str->ast (format nil ".DATA~%~tB 1 2 3 4 5 6 7 8~%"))))) + +(test esrap-data-triple + (is (equal + '(parse::p + (parse::d + 5 6 7 8 4 3 5)) + (esrap:parse 'parse:str->ast (format nil ".DATA~%~tC 5 6 7 8~%~tD 4 +~tE 3 5~%"))))) + +(test esrap-data-lazy-spaces + (is (equal + '(parse::p + (parse::d + 5 6 7 8 4 3 5)) + (esrap:parse 'parse:str->ast (format nil "~%~t.DATA~t~%F 5 6 7 8~t~%G 4 +H 3 5~%"))))) + +(test esrap-data-full + (is (equal + '(parse::p + (parse::d + 1 2 3 4 3 0) + (parse::x + (parse::i "LOAD" (parse::rr 5) (parse::rr 0) (parse::var "S")) + (parse::i "LOAD" (parse::rr 10) (parse::rr 0) (parse::var "ARR")) + (parse::i "LOAD" (parse::rr 6) (parse::rr 0) (parse::var "I")) + (parse::j "JRL" (parse::rr 0) (parse::l "CMP")) + (parse::r "ADD" (parse::rr 10) (parse::rr 6) (parse::rr 9)) + (parse::i "ADDI" (parse::rr 6) (parse::rr 6) (parse::imm 1)) + (parse::r "CMP" (parse::rr 6) (parse::rr 5) (parse::rr 0)) + (parse::j "BGT" (parse::rr 0) (parse::l "L")))) + (esrap:parse 'parse:str->ast (format nil " +.DATA + ARR 1 2 3 4 + S 3 + I 0 + +.TEXT + LOAD $5 S + LOAD $10 ARR + LOAD $6 I + JRL CMP +L: + ADD $9 $10 $6 + ADDI $6 $6 0X1 +CMP: + CMP $6 $5 + BGT L~%"))))) |