; [ʞ] 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))
(def (total size_t) 0)

(def (main int (argc int) (argv (array (ptr char))))
	 (ret (call sayhello "dumbass")))

(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)
)
