aboutsummaryrefslogtreecommitdiffstats
path: root/ir1.csc
diff options
context:
space:
mode:
Diffstat (limited to 'ir1.csc')
-rw-r--r--ir1.csc213
1 files changed, 213 insertions, 0 deletions
diff --git a/ir1.csc b/ir1.csc
new file mode 100644
index 0000000..53dacc1
--- /dev/null
+++ b/ir1.csc
@@ -0,0 +1,213 @@
+(define-library (csc ir1)
+ (export
+ call-arguments
+ call-procedure
+ call?
+ constant-expression
+ constant?
+ if-alternate
+ if-consequent
+ if-test
+ if?
+ lambda-body
+ lambda-case-alternate
+ lambda-case-arguments
+ lambda-case-body
+ lambda-case-gensyms
+ lambda-case-rest
+ lambda-case?
+ lambda?
+ letrec-expression
+ letrec-gensyms
+ letrec-in-order?
+ letrec-names
+ letrec-values
+ letrec?
+ lexical-ref-gensym
+ lexical-ref-name
+ lexical-ref?
+ lexical-set-expression
+ lexical-set-gensym
+ lexical-set-name
+ lexical-set?
+ library-ref-library
+ library-ref-name
+ library-ref-public?
+ library-ref?
+ library-set-expression
+ library-set-library
+ library-set-name
+ library-set-public?
+ library-set?
+ make-call
+ make-constant
+ make-if
+ make-lambda
+ make-lambda-case
+ make-letrec
+ make-lexical-ref
+ make-lexical-set
+ make-library-ref
+ make-library-set
+ make-sequence
+ make-toplevel-define
+ make-void
+ sequence-head
+ sequence-tail
+ sequence?
+ toplevel-define-expression
+ toplevel-define-name
+ toplevel-define?
+ void?)
+ (import (scheme base))
+ (begin
+ ; This library defines the intermediate representation IR1. An expression
+ ; in IR1 has one of the following forms (plagiarized from Guile's
+ ; Tree-IL).
+
+
+ ; <void>
+ ; An empty expression. In practice, equivalent to Scheme's (if #f #f).
+ (define-record-type <void>
+ (make-void)
+ void?)
+
+
+ ; <constant> expression
+ ; Constant is used to include literal constants in scheme code.
+ (define-record-type <constant>
+ (make-constant expression)
+ constant?
+ (expression constant-expression))
+
+
+ ; <lexical-ref> name gensym
+ ; A reference to a lexically-bound variable. The name is the original name
+ ; of the variable in the source program. gensym is a unique identifier for
+ ; this variable.
+ (define-record-type <lexical-ref>
+ (make-lexical-ref name gensym)
+ lexical-ref?
+ (name lexical-ref-name)
+ (gensym lexical-ref-gensym))
+
+
+ ; <lexical-set> name gensym expression
+ ; Sets a lexically-bound variable.
+ (define-record-type <lexical-set>
+ (make-lexical-set name gensym expression)
+ lexical-set?
+ (name lexical-set-name)
+ (gensym lexical-set-gensym)
+ (expression lexical-set-expression))
+
+
+ ; <library-ref> library name public?
+ ; A reference to a variable in a specific library. library should be the name
+ ; of the library, e.g. (scheme base).
+ ;
+ ; If public? is true, name will be looked up in library's public interface,
+ ; otherwise it will be looked up among the library's private bindings.
+ (define-record-type <library-ref>
+ (make-library-ref library name public?)
+ library-ref?
+ (library library-ref-library)
+ (name library-ref-name)
+ (public? library-ref-public?))
+
+
+ ; <library-set> library name public? expression
+ ; Sets a variable in a specific library.
+ (define-record-type <library-set>
+ (make-library-set library name public? expression)
+ library-set?
+ (library library-set-library)
+ (name library-set-name)
+ (public? library-set-public?)
+ (expression library-set-expression))
+
+
+ ; <toplevel-define> name expression
+ ; Defines a new variable in the current library.
+ (define-record-type <toplevel-define>
+ (make-toplevel-define name expression)
+ toplevel-define?
+ (name toplevel-define-name)
+ (expression toplevel-define-expression))
+
+
+ ; <if> test consequent alternate
+ ; A conditional.
+ (define-record-type <if>
+ (make-if test consequent alternate)
+ if?
+ (test if-test)
+ (consequent if-consequent)
+ (alternate if-alternate))
+
+
+ ; <call> procedure arguments
+ ; A procedure call. The procedure and arguments are evaluated in an
+ ; unspecified order, and the resulting procedure is passed the
+ ; resulting arguments.
+ (define-record-type <call>
+ (make-call procedure arguments)
+ call?
+ (procedure call-procedure)
+ (arguments call-arguments))
+
+
+ ; <sequence> head tail
+ ; Evaluate head, ignoring any result. Then tail is evaluated.
+ (define-record-type <sequence>
+ (make-sequence head tail)
+ sequence?
+ (head sequence-head)
+ (tail sequence-tail))
+
+
+ ; <lambda> body
+ ; A closure. body is an expression of type <lambda-case>.
+ (define-record-type <lambda>
+ (make-lambda body)
+ lambda?
+ (body lambda-body))
+
+
+ ; <lambda-case> arguments rest gensyms body alternate
+ ; One clause of a case-lambda. A lambda expression in Scheme is treated as
+ ; a case-lambda with one clause.
+ ;
+ ; arguments is a list of the procedures arguments, as symbols. rest is the
+ ; name of the rest argument, or #f. gensyms is a list of gensyms
+ ; corresponding to all arguments: first all of the normal arguments, then
+ ; the rest argument if any.
+ ;
+ ; body is the name of the clause. If the procedure is called with an
+ ; appropriate number of arguments, body is evaluated in tail position.
+ ; Otherwise if there is an alternate, it should be a <lambda-case>
+ ; expression, representing the next clause to try. If there is no
+ ; alternate, an error is signaled.
+ (define-record-type <lambda-case>
+ (make-lambda-case arguments rest gensyms body alternate)
+ lambda-case?
+ (arguments lambda-case-arguments)
+ (rest lambda-case-rest)
+ (gensyms lambda-case-gensyms)
+ (body lambda-case-body)
+ (alternate lambda-case-alternate))
+
+
+ ; <letrec> in-order? names gensyms values expression
+ ; Lexical binding, like Scheme's letrec, or letrec* if in-order? is true.
+ ; names are the original binding names, gensyms are gensyms corresponding
+ ; to the names, and values are IR1 expressions for the values. expression
+ ; is a single IR1 expression.
+ (define-record-type <letrec>
+ (make-letrec in-order? names gensyms values expression)
+ letrec?
+ (in-order? letrec-in-order?)
+ (names letrec-names)
+ (gensyms letrec-gensyms)
+ (values letrec-values)
+ (expression letrec-expression))))