summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--input/add-loop-directive.asm21
-rw-r--r--src/package.lisp6
-rw-r--r--src/parse.lisp21
-rw-r--r--t/parse.lisp116
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~%")))))