util  Check-in [844294c3a4]

Overview
Comment:add support for conditionals, array indexing, and reference-taking
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 844294c3a498c4ada3ad69a274503e6fab3186c549ecba0874ed764ccfff972c
User & Date: lexi on 2019-07-24 22:36:50
Other Links: manifest | tags
Context
2019-07-25
11:06
add nkvd.c and make infra check-in: 7ba40af07e user: lexi tags: trunk
2019-07-24
22:36
add support for conditionals, array indexing, and reference-taking check-in: 844294c3a4 user: lexi tags: trunk
2019-07-23
12:32
add sexcp check-in: 520b38deac user: lexi tags: trunk
Changes

Modified sexpc/example.cse from [58b3a515c7] to [d3af63ab24].

    14     14      ; (@ … ) introduces a block of Scheme code that
    15     15      ; is evaluated in the program's environment, but
    16     16      ; whose value is silently ignored. this makes it
    17     17      ; good for defining globals you intend to use
    18     18      ; later in the program with (* … ) or (= … )
    19     19      ; blocks - see the paragraph below
    20     20      (define (sayl str)
    21         -	 `(add-> total (call write 1
           21  +	  `(add-> total (call write 1
    22     22   	  ; the return value of a scheme expression will
    23     23   	  ; be evaluated just like any other expression
    24     24   	  ; and transformed into C code, so we can rely
    25     25   	  ; on existing syntax instead of haven't to
    26     26   	  ; generate raw strings of C
    27     27   			,(string-append str "\\n")
    28     28   			,(+ 1 (string-length str))))))
    29     29   
    30     30   (decl sayhello ((ptr char) → int))
           31  +(decl usage (() => ()))
    31     32   (def (total size_t) 0)
    32     33   
    33     34   (def (main int (argc int) (argv (array (ptr char))))
    34         -	 (ret (call sayhello "dumbass")))
           35  +	 (def (voidptr (ptr ())) (cast (ptr ()) argv))
           36  +	 (cond ((neq argc 2) (call usage))
           37  +		   (else (call sayhello (idx argv 1))))) 
    35     38   
    36     39   (def (sayhello int (name (ptr char)))
    37     40   	 (* sayl "hello…")
    38     41   	 ; a list prefixed with * indicates that it 
    39     42   	 ; should be evaluated as a scheme expression
    40     43   	 ; and its result then processed, instead of
    41     44   	 ; being processed directly like (call) or
................................................................................
    42     45   	 ; (def). scheme expressions may be inserted
    43     46   	 ; anywhere a normal sexpc expression can. or
    44     47   	 ; we could instead write (= (sayl "hello…"))
    45     48   	 ; to accomplish the same effect; (= … ) is
    46     49   	 ; really just shorthand for (* begin … )
    47     50   
    48     51   	 (call write 1 name (call strlen name))
    49         -	 (ret total)
    50         -)
           52  +	 (ret total))
           53  +
           54  +(def (usage void ())
           55  +	 (* sayl "usage: example <name>"))
           56  +

Modified sexpc/sexpc.scm from [a27b738777] to [46b6c9a575].

    24     24   
    25     25   (import (chicken process-context))
    26     26   (import (chicken condition))
    27     27   (import (chicken pretty-print))
    28     28   (import (chicken io))
    29     29   (include "../scmlib/lisp-macro.scm")
    30     30   
    31         -(: *code-depth* integer)
    32         -(define *code-depth* 0) ; im sry
    33         -
    34         -(: indent (string -> string))
    35         -(define (indent str)
    36         -  (define (iterate n)
    37         -	(if (eq? n 0) str
    38         -		(string-append "\t" (iterate (- n 1)))))
    39         -  (iterate *code-depth*))
    40     31   (define (first fst . lst) fst)
    41     32   
    42     33   (: string-reduce (list --> string))
    43     34   (: words->string (list --> string))
    44     35   (: separate (string list --> string))
    45     36   (define (string-reduce lst) (foldl string-append "" lst))
    46     37   (define (words->string lst) (foldl (lambda (a b) (string-append a " " b)) "" lst))
................................................................................
    75     66   		(else (abort '(exn syntax declare)))))
    76     67   
    77     68   (define (c-define body)
    78     69     (cond
    79     70   	((and (list? (car body)) (>= (length body) 2))
    80     71   	 (let ([contents (words->string (map (lambda(x) (eval-code #f x)) (cdr body)))])
    81     72   	   (string-append (c-declare (car body))
    82         -					  (if (>= (length (car body)) 3) (string-append " {\n" contents "\n}")
           73  +					  (if (>= (length (car body)) 3) (string-append " {" contents "}")
    83     74   						  (string-append " = " contents)))))
    84     75   	(else (abort '(exn syntax define)))))
    85     76   
    86     77   (: c-call-function (list -> string))
    87     78   (define (c-call-function body)
    88     79     (unless (> (length body) 0) (abort '(exn parse call)))
    89     80     (string-append
    90     81   	(eval-code #t (car body)) "(" (separate "," (map (lambda(x) (eval-code #t x)) (cdr body))) ")"))
           82  +
           83  +(: c-array-index (list -> string))
           84  +(define (c-array-index body)
           85  +  (unless (= (length body) 2) (abort '(exn parse call)))
           86  +  (string-append
           87  +	(eval-code #t (car body))
           88  +	"[" (eval-code #t (cadr body)) "]"))
           89  +
           90  +(: c-conditional (list -> string))
           91  +(define (c-conditional body)
           92  +  (unless (> (length body) 0) (abort '(exn parse cond)))
           93  +  (define (mk-block acc code)
           94  +	(string-append
           95  +		(if (eq? 'else (car code)) (string-append acc "else {")
           96  +			(string-append acc
           97  +			  (if (equal? acc "") "if (" " else if (")
           98  +			  (eval-code #t (car code)) ") {"))
           99  +
          100  +		(string-reduce (map (lambda(x)(eval-code #f x)) (cdr code)))
          101  +		"}"
          102  +		))
          103  +  (foldl mk-block "" body))
          104  +
    91    105   
    92    106   (define (c-cpp-include body)
    93    107     (case (length body)
    94    108   	((1) (if (string? (car body)) (string-append "#include \"" (car body) "\"\n")
    95    109   			 (abort '(exn syntax include))))
    96    110   	((2) (if (and (eqv? (car body) 'sys)
    97    111   				  (string? (cadr body))) (string-append "#include <" (cadr body) ">\n")
................................................................................
   117    131   		  ((and (list? a) (= (length a) 2)) ((eval-type (cadr a)) (car a)))
   118    132   		  ((list? a) ((eval-type a)""))
   119    133   		  (else (abort '(exn syntax function-declare argument)))))
   120    134     (let ([arg-str (separate ", " (map parse-arg args))]
   121    135   		[ret-fn (eval-type ret)])
   122    136   	(ret-fn (string-append (ensure-string name) "(" arg-str ")"))))
   123    137   
   124         -(define-macro (with-deeper-context . body)
   125         -			  `(begin
   126         -				 (set! *code-depth* (+ 1 *code-depth*))
   127         -				 (first
   128         -				   ,@body
   129         -				   (set! *code-depth* (- *code-depth* 1))
   130         -				   )))
   131         -
   132    138   (: c-statement (string -> string))
   133         -(define (c-statement s) (indent (with-deeper-context (string-append s ";\n"))))
          139  +(define (c-statement s) (string-append s ";"))
   134    140   
   135    141   (: eval-type ((or null symbol list) -> ((or symbol string) -> string)))
   136    142   (define (eval-type t)
   137    143     ; a type object is a function that is called with a name to
   138    144     ; generate a definition. this is necessary for the case of
   139    145     ; arrays and function pointers, which require special syntax
   140    146     (: simple ((or string symbol) --> string))
................................................................................
   181    187   				   ('uint (simple "unsigned int"))
   182    188   				   ('ulong (simple "unsigned long"))
   183    189   				   ('ullong (simple "unsigned long long"))
   184    190   				   ('llong (simple "long long"))
   185    191   				   ('ldouble (simple "long double"))
   186    192   				   ('u128 (simple "unsigned __int128_t"))
   187    193   				   ('s128 (simple "__int128_t"))
          194  +				   ('ptr (simple "void*"))
   188    195   				   (else (simple (symbol->string t)))))
   189    196   	((list? t) (parse-type t))
   190    197   	((string? t) (simple t))
   191    198   	(else (abort '(exn syntax)))))
   192    199   
   193    200   (define (c-construct type name body)
   194         -  (string-append type " " name " {\n"
   195         -				 (string-reduce (map (lambda(x) (indent (eval-code #f x))) body))
   196         -				 "\n}"))
          201  +  (string-append type " " name " {"
          202  +				 (string-reduce (map (lambda(x) (eval-code #f x)) body))
          203  +				 "}"))
   197    204   
   198    205   (define (c-fn-return body)
   199    206     (string-append "return " (string-reduce (map (lambda(x) (eval-code #t x)) body))))
   200    207   
   201         -(define (c-math-op op body)
   202         -  (unless (= 2 (length body)) (abort '(exn syntax math)))
          208  +(define (c-binary-op op body)
          209  +  (unless (= 2 (length body)) (abort '(exn syntax binary-op)))
   203    210     (string-append "((" (eval-code #t (car body)) ")" op "(" (eval-code #t (cadr body)) "))"))
   204    211   	  
   205         -(define (inter s x) (print* "-- " s ": ") (pretty-print x) x)
          212  +(define (c-unary-op op body)
          213  +  (unless (= 1 (length body)) (abort '(exn syntax unary-op)))
          214  +  (string-append "(" op "(" (eval-code #t (car body)) "))"))
          215  +
          216  +(define (c-typecast body)
          217  +  (unless (= 2 (length body)) (abort '(exn syntax binary-op)))
          218  +  (string-append "((" ((eval-type (car body))"") ")" (eval-code #t (cadr body)) ")"))
          219  +	  
          220  +(define (wiretap s x) (print* "-- " s ": ") (pretty-print x) x)
   206    221   (: eval-code (boolean list -> string))
   207    222   (define (eval-code inexpr data) 
   208    223     (define (ctx x) inexpr (if (eq? inexpr #t) x (c-statement x)))
   209         -  (define (deepen n) (set! *code-depth* (+ *code-depth* n)))
   210    224     (: dispatch (list -> string))
   211    225     (define (dispatch form body)
   212    226   	(case form
   213    227   	  ('* (eval-code inexpr (evaluate-list body)))
   214    228   	  ('= (eval-code inexpr (evaluate-list (cons 'begin body))))
   215    229   	  ('@ (eval (cons 'begin body)) "")
   216    230   	  ('use (c-cpp-include body))
   217         -	  ('def  (first (c-statement (with-deeper-context (c-define body))) ))
   218         -	  ('decl  (first (c-statement (with-deeper-context (c-declare body))) ))
          231  +	  ('def  (first (c-statement (c-define body))) )
          232  +	  ('decl  (first (c-statement (c-declare body)) ))
   219    233   	  ('call (ctx (c-call-function body)))
          234  +	  ('cond (c-statement (c-conditional body)))
   220    235   	  ('list  (first (string-append "{" (separate "," (map (lambda(x) (eval-code #t x)) body)) "}") ))
   221    236   	  ('struct  (first (ctx (c-construct "struct" (car form) (cdr form))) ))
   222    237   	  ('enum    (first (ctx (c-construct "enum"   (car form) (cdr form))) ))
   223    238   	  ('ret (c-statement (c-fn-return body)))
   224         -	  ('add (c-math-op "+" body))
   225         -	  ('add-> (ctx (c-math-op "+=" body)))
   226         -	  ('sub (c-math-op "-" body))
   227         -	  ('sub-> (ctx (c-math-op "-=" body)))
   228         -	  ('mul (c-math-op "*" body))
   229         -	  ('mul-> (ctx (c-math-op "*=" body)))
   230         -	  ('div (c-math-op "/" body))
   231         -	  ('div-> (ctx (c-math-op "/=" body)))
   232         -	  ('== (c-math-op "==" body))
   233         -	  ('-> (ctx (c-math-op "=" body)))
   234         -	  ('→  (ctx (c-math-op "=" body)))
          239  +	  ('cast (c-typecast body))
          240  +	  ('idx (c-array-index body))
          241  +	  ('add (c-binary-op "+" body))
          242  +	  ('add-> (ctx (c-binary-op "+=" body)))
          243  +	  ('sub (c-binary-op "-" body))
          244  +	  ('sub-> (ctx (c-binary-op "-=" body)))
          245  +	  ('mul (c-binary-op "*" body))
          246  +	  ('mul-> (ctx (c-binary-op "*=" body)))
          247  +	  ('div (c-binary-op "/" body))
          248  +	  ('div-> (ctx (c-binary-op "/=" body)))
          249  +	  ('ref (c-unary-op "&" body))
          250  +	  ('eq (c-binary-op "==" body))
          251  +	  ('neq (c-binary-op "!=" body))
          252  +	  ('gte (c-binary-op ">=" body))
          253  +	  ('lte (c-binary-op "<=" body))
          254  +	  ('lt (c-binary-op "<" body))
          255  +	  ('gt (c-binary-op ">" body))
          256  +	  ('-> (ctx (c-binary-op "=" body)))
          257  +	  ('→  (ctx (c-binary-op "=" body)))
   235    258   	  ('; ";")
   236    259   	  (else (string-append "<UNFOUND FORM " (symbol->string form) ">")) 
   237    260   	  )))
   238    261     (cond
   239    262   	((null? data) "")
   240    263   	((symbol? data) (symbol->string data))
   241    264   	((string? data) (string-append "\"" data "\""))

Modified sexpc/type-tests.scm from [47bc0863a3] to [3a7d364dcb].

    17     17   	(const (ptr float))
    18     18   	(ptr int)
    19     19   	(ullong schar -> (ptr (bool u128 -> ldouble)))
    20     20   	(int -> chungus_t)
    21     21   	(ptr (int -> chungus_t))
    22     22   	(array 5 (ptr (int -> chungus_t)))
    23     23   	((array 5 (ptr int)) -> (const (ptr (array 3 int))))
    24         -    ; int (((*const (v(int (*(())[5])))))[3])
    25         -    ; int (* const v(int *[5]))[3]
    26         -(array (const (ptr (char u128 -> (ptr (array 5 bool))))))
           24  +	(array (const (ptr (char u128 -> (ptr (array 5 bool))))))
    27     25   	
    28     26   	(array 5 (const (ref char)))))
    29     27   
    30     28   (map test tests)