aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2022-06-30 00:23:06 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2022-07-07 21:17:22 +0200
commitd3abced2923c409ed27393f6ff554b5638c025e2 (patch)
treefd3da9db46e2ad12387c5723c69b29faad3be9b2
parentC-parser add strings. (diff)
downloadcalp-d3abced2923c409ed27393f6ff554b5638c025e2.tar.gz
calp-d3abced2923c409ed27393f6ff554b5638c025e2.tar.xz
C parser add unary minus.
-rw-r--r--module/c/lex.scm10
-rw-r--r--module/c/parse.scm5
-rw-r--r--tests/test/cpp.scm54
3 files changed, 60 insertions, 9 deletions
diff --git a/module/c/lex.scm b/module/c/lex.scm
index 30fcd3c1..2b024f1c 100644
--- a/module/c/lex.scm
+++ b/module/c/lex.scm
@@ -108,14 +108,18 @@
base-10-digit))))
(define-peg-pattern prefix-operator all
- (or "!" "~" "*" "&" "++" "--" "+" "-"))
+ ;; It's important that ++ and -- are BEFORE + and -
+ ;; otherwise the first + is found, leaving the second +, which fails
+ ;; to lex since it's an invalid token
+ (or "*" "&" "++" "--"
+ "!" "~" "+" "-"))
+
;;; Note that stacked pre or postfix operators without parenthesis
;;; dosen't work. So `*&C' is invalid, while `*(&C)' is valid.
(define-peg-pattern prefix all
- (and prefix-operator sp (or variable group funcall #; postfix
- )))
+ (and prefix-operator sp (or variable group funcall literal)))
(define-peg-pattern postfix-operator all
(or "++" "--" "*"))
diff --git a/module/c/parse.scm b/module/c/parse.scm
index ad716132..15240bc1 100644
--- a/module/c/parse.scm
+++ b/module/c/parse.scm
@@ -123,6 +123,7 @@
((&) 'pointer)
((++) 'pre-increment)
((--) 'pre-decrement)
+ ((-) '-)
(else (scm-error 'c-parse-error "parse-lexeme-tree"
"Unknown prefix operator ~s"
(list op) #f)))]
@@ -150,6 +151,10 @@
`(,(parse-lexeme-tree op)
,(parse-lexeme-tree arg))]
+
+
+
+
;; resolved-operator and ternary are the return "types"
;; of resolve-order-of-operations
[(('resolved-operator op) args ...)
diff --git a/tests/test/cpp.scm b/tests/test/cpp.scm
index f7b11296..2cb4266d 100644
--- a/tests/test/cpp.scm
+++ b/tests/test/cpp.scm
@@ -118,6 +118,48 @@
(integer (base-10 "2")))) (lex form))
(test-equal '(+ 2 2 2) (run form)))
+(test-group "Unary minus"
+ (test-group "Without space"
+ (let ((form "-1"))
+ (test-equal '(prefix (prefix-operator "-")
+ (integer (base-10 "1")))
+ (lex form))
+ (test-equal '(- 1) (run form))))
+
+ (test-group "With space"
+ (let ((form "- 1"))
+ (test-equal '(prefix (prefix-operator "-")
+ (integer (base-10 "1")))
+ (lex form))
+ (test-equal '(- 1) (run form))))
+
+ (test-group "Before variable"
+ (let ((form "-x"))
+ (test-equal '(prefix (prefix-operator "-")
+ (variable "x"))
+ (lex form))
+ (test-equal '(- x) (run form))))
+
+ (test-group "Before infix"
+ (let ((form "-x+3"))
+ (test-equal '(infix (prefix (prefix-operator "-")
+ (variable "x"))
+ (operator "+")
+ (integer (base-10 "3")))
+ (lex form))
+ (test-equal '(+ (- x) 3)
+ (run form))))
+
+ (test-group "Inside infix expression"
+ (let ((form "x+-3"))
+ (test-equal '(infix (variable "x")
+ (operator "+")
+ (prefix (prefix-operator "-")
+ (integer (base-10 "3"))))
+ (lex form))
+ (test-equal '(+ x (- 3)) (run form))))
+ )
+
@@ -224,6 +266,12 @@
(test-equal '(funcall _IOR (#{,}# 116 19 (struct-type termios))) (run form)))
+;; TODO concatenation rules
+;; #define __CONCAT(x,y) __CONCAT1(x,y)
+;; #define __CONCAT1(x,y) x ## y
+;; #define __CONSTANT_CFSTRINGS__ 1
+;; #define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+
(test-group "Token concatenation"
(let ((form "x ## y"))
(test-equal '() (lex form))
@@ -426,9 +474,3 @@
(test-equal '(funcall __attribute__
(funcall __aligned__ x))
(run form)))
-
-;; TODO concatenation rules
-;; #define __CONCAT(x,y) __CONCAT1(x,y)
-;; #define __CONCAT1(x,y) x ## y
-;; #define __CONSTANT_CFSTRINGS__ 1
-;; #define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s)