util  example.cse at [e02ae59ffd]

File sexpc/example.cse artifact d3af63ab24 part of check-in e02ae59ffd


; [ʞ] example.cse
;  ~ lexi hale <lexi@hale.su>
;  - vim: ft=scheme
;  © CCO / public domain
;  $ ./sexpc example.cse
;  ? this file is an example program that can be
;    transpiled to valid C with sexpc.scm.
(use sys "unistd.h")
(use sys "stddef.h")
(use sys "stdint.h")
(use sys "string.h")

(@ (: sayl (string -> list))
   ; (@ … ) introduces a block of Scheme code that
   ; is evaluated in the program's environment, but
   ; whose value is silently ignored. this makes it
   ; good for defining globals you intend to use
   ; later in the program with (* … ) or (= … )
   ; blocks - see the paragraph below
   (define (sayl str)
	  `(add-> total (call write 1
	  ; the return value of a scheme expression will
	  ; be evaluated just like any other expression
	  ; and transformed into C code, so we can rely
	  ; on existing syntax instead of haven't to
	  ; generate raw strings of C
			,(string-append str "\\n")
			,(+ 1 (string-length str))))))

(decl sayhello ((ptr char) → int))
(decl usage (() => ()))
(def (total size_t) 0)

(def (main int (argc int) (argv (array (ptr char))))
	 (def (voidptr (ptr ())) (cast (ptr ()) argv))
	 (cond ((neq argc 2) (call usage))
		   (else (call sayhello (idx argv 1))))) 

(def (sayhello int (name (ptr char)))
	 (* sayl "hello…")
	 ; a list prefixed with * indicates that it 
	 ; should be evaluated as a scheme expression
	 ; and its result then processed, instead of
	 ; being processed directly like (call) or
	 ; (def). scheme expressions may be inserted
	 ; anywhere a normal sexpc expression can. or
	 ; we could instead write (= (sayl "hello…"))
	 ; to accomplish the same effect; (= … ) is
	 ; really just shorthand for (* begin … )

	 (call write 1 name (call strlen name))
	 (ret total))

(def (usage void ())
	 (* sayl "usage: example <name>"))