diff --git a/collects/honu/ast.ss b/collects/honu/ast.ss deleted file mode 100644 index 7193f42829..0000000000 --- a/collects/honu/ast.ss +++ /dev/null @@ -1,298 +0,0 @@ -(module ast mzscheme - - (require (lib "contract.ss") - (planet "hierarchy.ss" ("dherman" "struct.plt" 2 1)) - (planet "inspector.ss" ("dherman" "inspector.plt" 1 0)) - (planet "contract-utils.ss" ("cobbe" "contract-utils.plt" 1 0)) - ) - - (with-public-inspector - (define-hierarchy/provide/contract - - (ast ; parent structure for AST nodes - ([syntax (optional/c syntax?)] ; all nodes store syntax locations - ) - - (ast:type () ; parent structure for types - - (ast:type:top ()) ; "void" or "unit" type - (ast:type:bot ()) ; "error" type, or for non-returning operations - - (ast:type:object () ; Object type - (ast:type:object:any ()) ; Distinguished Any type, top of hierarchy - (ast:type:object:null ()) ; Type of null, bottom of hierarchy - (ast:type:object:iface ; Interface type - ([name identifier?] ; name of the interface - ))) - - (ast:type:primitive ; Builtin type (int, char, bool, etc.) - ([name symbol?] ; builtins come from a fixed set of names - )) - - (ast:type:tuple ; Tuple type - ([elems (listof ast:type?)] ; types of each tuple element - )) - - (ast:type:partial/tuple ; Tuple type as inferred from selector - ([position integer?] ; position at which type is known - [elem ast:type?] ; type at that position - )) - - (ast:type:function ; Function type (without dispatch) - ([input ast:type?] ; input type - [output ast:type?] ; output type - )) - - (ast:type:method ; Method type (with receiver dispatch) - ([receiver ast:type:object?] ; type of the method's receiver - [input ast:type?] ; input type - [output ast:type?] ; input type - )) - ) - - (ast:defn () ; parent structure for top-level definitions - - (ast:defn:iface ; Interface definitions - ([name identifier?] ; interface name - [supers (listof ast:type:object?)] ; parent interfaces - [members (listof ast:iface/member?)] ; members (methods and fields) - )) - - (ast:defn:class ; Class definitions - ([name identifier?] ; interface name - [self-type ast:type:object?] ; class's type internally and for subclassing - [final? boolean?] ; whether the class may be extended - [client-types (listof ast:type:object?)] ; implemented interfaces - [formals (listof ast:formal?)] ; constructor arguments - [members (listof ast:class/member?)] ; member definitions - [exports (listof ast:export?)] ; export declarations - )) - - (ast:defn:mixin ; Mixin definition - ([name identifier?] ; mixin name - [self-type ast:type:object?] ; mixin's type internally and for subclassing - [super-type ast:type:object?] ; input interface - [final? boolean?] ; whether the mixin can be extended - [client-types (listof ast:type:object?)] ; implemented interfaces - [formals (listof ast:formal?)] ; constructor arguments - [super-formals (listof ast:formal?)] ; expected parent arguments - [super-new ast:super-new?] ; parent initialization - [pre-members (listof ast:class/member?)] ; members defined before super-new - [post-members (listof ast:class/member?)] ; members defined after super-new - [exports (listof ast:export?)] ; export declarations - )) - - (ast:defn:subclass ; Subclass definition (applies a mixin to a class) - ([name identifier?] ; new class's name - [base identifier?] ; superclass - [mixin identifier?] ; applied mixin - )) - - (ast:defn:structure ; Structure definition (class and type defined at once) - ([name identifier?] ; structure name - [self-type ast:type:object?] ; internal/subclassing type (how does this relate to "structure" type?) - [final? boolean?] ; whether the structure can be extended - [client-types (listof ast:type:object?)] ; implemented interfaces - [formals (listof ast:formal?)] ; constructor arguments - [members (listof ast:class/member?)] ; member definitions - [exports (listof ast:export?)] ; export declarations - )) - - (ast:defn:substructure ; Substructure definition (defines and instantiates subclassing) - ([name identifier?] ; substructure name - [self-type ast:type:object?] ; internal/subclassing type - [super-class identifier?] ; parent class - [super-type ast:type:object?] ; parent interface - [final? boolean?] ; whether the substructure can be extended - [client-types (listof ast:type:object?)] ; implemented interfaces - [formals (listof ast:formal?)] ; constructor arguments - [super-formals (listof ast:formal?)] ; expected parent arguments - [super-new ast:super-new?] ; parent initialization - [pre-members (listof ast:class/member?)] ; members defined before super-new - [post-members (listof ast:class/member?)] ; members defined after super-new - [exports (listof ast:export?)] ; export declarations - )) - - (ast:defn:function ; Function definition - ([name identifier?] ; function name - [return-type ast:type?] ; output type - [formals (listof ast:formal?)] ; input names and types - [body ast:expr?] ; function implementation - )) - - (ast:defn:binding ; Top-level variable binding - ([names (listof identifier?)] ; variable name or names (if binding a tuple) - [types (listof ast:type?)] ; variable type(s) - [init ast:expr?] ; expression providing the bound value(s) - )) - - ) - - (ast:iface/member ; Member declared in an interface - ([name identifier?] ; member name - ) - (ast:iface/member:field ; Field of an interface - ([type ast:type?] ; field type - )) - (ast:iface/member:method ; Method of an interface - ([return-type ast:type?] ; output type - [formal-types (listof ast:type?)] ; input types - ))) - - (ast:class/member ; Member defined in a class/mixin - ([name identifier?] ; member name - ) - (ast:class/member:field ; Field of a class - ([type ast:type?] ; field type - [default (optional/c ast:expr?)] ; default value - )) - (ast:class/member:field/formal ; Field and constructor argument - ([type ast:type?] ; field type - [default (optional/c ast:expr?)] ; default value - )) - (ast:class/member:method ; Method of a class - ([return-type ast:type?] ; output type - [formals (listof ast:formal?)] ; method arguments - [body ast:expr?] ; method implementation - ))) - - (ast:super-new ; Parent class initializer - ([args (listof ast:named/arg?)] ; constructor arguments - )) - - (ast:expr () ; Parent structure for expressions - - (ast:expr:self ()) ; Self-reference within an object - - (ast:expr:var ; Variable reference - ([name identifier?] ; variable name - )) - - (ast:expr:assign ; Assignment - ([lhs ast:expr?] ; assignment destination - [rhs ast:expr?] ; assignment source - )) - - (ast:expr:apply ; Function call - ([func ast:expr?] ; invoked function - [arg ast:expr?] ; actual arguments - )) - - (ast:expr:literal ; Primitive value - ([type ast:type?] ; literal type - [value syntax?] ; literal value - )) - - (ast:expr:unary/op ; Prefix operation - ( - [name symbol?] ; operator name - [rator-stx syntax?] ; operator syntax - [rator-type (optional/c ast:type?)] ; operator type (presumably added by typechecker) - [arg ast:expr?] ; operator argument - )) - - (ast:expr:binary/op ; Infix operation - ( - [name symbol?] ; operator name - [rator-stx syntax?] ; operator syntax - [rator-type (optional/c ast:type?)] ; operator type (presumably added by typechecker) - [left ast:expr?] ; first argument - [right ast:expr?] ; second argument - )) - - (ast:expr:function ; Anonymous function value - ([return-type ast:type?] ; output type - [formals (listof ast:formal?)] ; arguments - [body ast:expr?] ; function implementation - )) - - (ast:expr:if ; Simple conditional - ([test ast:expr?] ; Boolean expression - [then ast:expr?] ; Result when true - [else ast:expr?] ; Result when false - )) - - (ast:expr:cast ; Typecast - ([object ast:expr?] ; value to cast - [type ast:type:object?] ; type of cast - )) - - (ast:expr:isa ; Type conditional - ([object ast:expr?] ; value to test - [type ast:type:object?] ; type of test - )) - - (ast:expr:member ; Access field or method - ([object (union ast:expr? (symbols 'my))] ; receiver - [object-type (optional/c ast:type:object?)] ; receiver type - [name identifier?] ; member name - [method? (union boolean? (symbols 'unknown))] ; whether member is a method or field - )) - - (ast:expr:let ; Local bindings - ([bindings (listof ast:defn:binding?)] ; new definitions - [body ast:expr?] ; expression in new scope - )) - - (ast:expr:sequence ; Sequential statements - ([statements (listof ast:expr?)] ; executed in order for effect only - [result ast:expr?] ; executed last and returned - )) - - (ast:expr:new ; Object construction - ([class identifier?] ; class to instantiate - [type (optional/c ast:type:object?)] ; static type of object (presumably added by typechecker) - [args (listof ast:named/arg?)] ; constructor arguments - )) - - (ast:expr:cond ; Multiple-branch conditional - ([clauses (listof ast:cond/clause?)] ; conditional clauses - [else ast:expr?] ; result if all else fails - )) - - (ast:expr:while ; Imperative recursion - ([test ast:expr?] ; controls loop - [body ast:expr?] ; loop body - )) - - (ast:expr:return ; Escapes function/method - ([result ast:expr?] ; returned value - )) - - (ast:expr:tuple ; Tuple constructor - ([elems (listof ast:expr?)] ; tuple elements - )) - - (ast:expr:tuple/select ; Tuple projection - ([position integer?] ; selected element - [arg ast:expr?] ; tuple expression - ))) - - (ast:export ; Export declaration - ([type ast:type:object?] ; exported type - [members (listof ast:export/member?)] ; exported members - )) - - (ast:formal ; Declared arguments - ([name identifier?] ; variable name - [type ast:type?] ; argument type - )) - - (ast:cond/clause ; Conditional branches - ([test ast:expr?] ; condition - [result ast:expr?] ; result if true - )) - - (ast:export/member ; Individual export specification - ([internal identifier?] ; name inside class/mixin - [external identifier?] ; name from interface - )) - - (ast:named/arg ; By-name arguments - ([name identifier?] ; argument name - [actual ast:expr?] ; argument value - )) - - ))) - - ) diff --git a/collects/honu/base.ss b/collects/honu/base.ss deleted file mode 100644 index 10883e9929..0000000000 --- a/collects/honu/base.ss +++ /dev/null @@ -1,84 +0,0 @@ -(module base mzscheme - - (require (lib "class.ss")) - - (define-syntax (honu:send stx) - (syntax-case stx () - [(_ obj msg arg ...) - #'(if (is-a? obj null%) - (error "Attempt to access member of null") - (send obj msg arg ...))])) - - (define null% - (class object% - (inspect #f) - (super-new))) - - (define null-obj (new null%)) - - (define Any<%> - (interface ())) - - (define (printString s) - (display s) - '()) - - (define (printLine s) - (display s) - (newline) - '()) - - (define (readChar arg-tuple) - (read-char)) - - (define (readLine arg-tuple) - (read-line)) - - (define (stringToInt s) - (let ([number (string->number s)]) - (if (and number (integer? number)) - number - (error (format "Tried to convert \"~a\" to an integer" s))))) - - (define (stringToFloat s) - (let ([number (string->number s)]) - (if (and number (inexact? number)) - number - (error (format "Tried to convert \"~a\" to an float" s))))) - - (define (intToString i) - (number->string i)) - - (define (floatToString f) - (number->string f)) - - (define (charToString c) - (string c)) - - (define (strlen s) - (string-length s)) - - (define (substr arg-tuple) - (let-values ([(s start end) (apply values arg-tuple)]) - (cond - [(< start 0) - (error (format "Start index for substr must be positive, got ~a" start))] - [(> start end) - (error (format "Start index (~a) must be <= end index (~a)" start end))] - [(> end (string-length s)) - (error (format "End index for substr must be <= strlen(s), got ~a" end))] - [else (substring s start end)]))) - - (define (charAt arg-tuple) - (let-values ([(s i) (apply values arg-tuple)]) - (cond - [(< i 0) - (error (format "Index for charAt must be non-negative, got ~a" i))] - [(> i (- (string-length s) 1)) - (error (format "Index for charAt must be < strlen(s), got ~a" i))] - [else (string-ref s i)]))) - - (provide (all-from mzscheme) - (rename ormap mz:ormap) - (all-from (lib "class.ss")) - (all-defined))) diff --git a/collects/honu/cce-notes.txt b/collects/honu/cce-notes.txt deleted file mode 100644 index af74503894..0000000000 --- a/collects/honu/cce-notes.txt +++ /dev/null @@ -1,41 +0,0 @@ -Todo: - -AST -- changed names in ast.ss, propagate to everywhere else -- added (some) contracts; add the rest and verify what's there -- finish writing, and use, define-structs[/provide[/contract]] -Mixin Sealing -- move to single, applicative environment -Test Suite Improvements -Numeric Library - ------------------------------------------------------------- - -File purposes: - -doc.txt: implementation notes -tool.ss: definition of language level -compile.ss: top-level compilation functions -util.ss: general functions (similar to list.ss) -tenv.ss: definition of type environment -- don't understand all the types defined -tenv-utils.ss: manipulate environments -base.ss: top-level honu definitions -ast.ss: ast structs -private/typechecker/type-utils.ss: simple type operations - ------------------------------------------------------------- - -General structure: - -3 phases: -- parser tools (-> AST) -- post-parsing - - static references to "my" references (my.x for static fields, etc.) - - references to "this" only in member access (this.x) or in casts ((IFace)this) - - adds casts to this.x - - simplify-ast : gather asts/sequences into big lets/sequences -. -. -. - diff --git a/collects/honu/compile.ss b/collects/honu/compile.ss deleted file mode 100644 index 3365c67ecc..0000000000 --- a/collects/honu/compile.ss +++ /dev/null @@ -1,62 +0,0 @@ -(module compile mzscheme - - (require (lib "boundmap.ss" "syntax") - (lib "contract.ss") - (lib "plt-match.ss") - "ast.ss" - "honu-context.ss" - "parameters.ss" - "readerr.ss" - "tenv.ss" - "tenv-utils.ss" - "parsers/post-parsing.ss" - "private/compiler/translate.ss" - "private/compiler/translate-expression.ss" - "private/typechecker/type-utils.ss" - "private/typechecker/typechecker.ss" - "private/typechecker/typecheck-expression.ss") - - (provide/contract [compile/defns - ((tenv? tenv? (listof ast:defn?)) - . ->* . - (any/c (listof (syntax/c any/c))))] - [compile/interaction - ((tenv? - tenv? - (union ast:defn:binding? ast:expr?)) - . ->* . - ((syntax/c any/c) - (union ast:type? false/c)))]) - (define (compile/defns tenv lenv pgm) - (parameterize ([current-type-environment tenv] - [current-lexical-environment lenv]) - (let ([pgm (post-parse-program (add-defns-to-tenv pgm))]) - (let ([checked (typecheck pgm)]) - (parameterize ([current-compile-context honu-compile-context]) - (translate checked)))))) - - (define (check-bound-names names) - (for-each (lambda (n) - (if (and n (get-lenv-entry n)) - (raise-read-error-with-stx - (format "~a already bound" (printable-key n)) - n))) - names)) - - (define (compile/interaction tenv lenv ast) - (parameterize ([current-type-environment tenv] - [current-lexical-environment lenv]) - (match (post-parse-interaction ast) - [(struct ast:defn:binding (stx names _ value)) - (check-bound-names names) - (let ([checked (typecheck-defn ast)]) - (parameterize ([current-compile-context honu-compile-context]) - (values (translate-defn checked) #f)))] - [else - (let-values ([(checked type) - (typecheck-expression - (wrap-lenv) (make-top-type #f) ast)]) - (parameterize ([current-compile-context honu-compile-context]) - (values (translate-expression checked) type)))]))) - ) - diff --git a/collects/honu/doc.txt b/collects/honu/doc.txt deleted file mode 100644 index f1408a45cd..0000000000 --- a/collects/honu/doc.txt +++ /dev/null @@ -1,409 +0,0 @@ -_Honu_ - -_TODO_ - - * Admit statements as elements of mixin bodies, i.e., - - struct ExamplesC() : Examples { - IStack s0 = new StackC(); - int d0 = s0.depth(); - s0.push(s0); - } - - should work. -- MF - - * Work out details of standard library, including boxed versions of - primitive types. - - * If you do have a standard library, document it please. -- MF - - * Let's add arrays. - - * Add new statement that uses positional initialization arguments. - - * Add autoboxing of primitive types. - - * Add generics (parametric polymorphism and bounded polymorphism). - RESEARCH! - -_Primitive types_ - - int - integers - float - floating point numbers - string - strings (double quoted) - bool - booleans (true, false) - char - characters (single quoted) - -_Built-in functions_ - -Error reporting: - -> error(string message) => 'a - - Raises an error and prints the string as an error message. - - Calls to error() do not return. - -Input/output: - -> printString(string message) => void - - Takes a string and prints it on the standard output. - -> printLine(string message) => void - - Like printString, but prints a newline after printing the string. - -> readChar() => char - - Reads a single character from the standard input. - -> readLine() => string - - Reads a line of text from the standard input. - -Conversions to string: - -> intToString(int val) => string - - Converts an integer to a string. - -> floatToString(float val) => string - - Converts a floating point number to a string. - -> charToString(char val) => string - - Converts a character to a string. - -String conversions: - -> stringToInt(string val) => int - - Converts a string to an integer. - - Raises an error if the string cannot be converted. - -> stringToFloat(string val) => float - - Converts a string to a floating point number. - - Raises an error if the string cannot be converted. - -String operations: - -> strlen(string s) => int - - Takes a string and returns the string length. - -> substr(string s, int start, int end) => string - - Takes a string, a start index, and an end index and - returns the corresponding substring. - - The indexes are zero-based. - - The start index cannot be negative or greater than the end index. - - The end index must be less than or equal to the string length. - -> charAt(string s, int i) => char - - Takes a string and an index into the string and returns - the corresponding character. - - The zero-based index cannot be negative and must be less - than the string length. - -Numeric operations: - -> sqrt(float f) => float - - Produces the square root of its argument. - -_Operators_ - -Unary operators: - -> ! : bool -> bool - - Boolean negation (not) - -> - : bool -> bool - - Arithmetic negation - -Binary operators: - -> || : bool * bool -> bool - - Boolean disjunction (or) - -> && : bool * bool -> bool - - Boolean conjunction (and) - -> == : bool * bool -> bool -> == : int * int -> bool -> == : char * char -> bool -> == : float * float -> bool -> == : string * string -> bool - - Equivalence for primitives (value equality) - -> == : Any * Any -> bool - - Identity for classes (pointer equality) - -> != (same types as ==) - - Boolean negation of equivalence/identity - -> ==== : Any * Any -> bool - - Equivalence for classes (value equality) - -> < : int * int -> bool -> < : float * float -> bool -> < : char * char -> bool -> < : string * string -> bool - - Less than (numeric / character set / lexiographic) - -> > (same types as <) - - Greater than - -> <= (same types as <) - - Less than or equal to - -> >= (same types as <) - - Greater than or equal to - -> + : int * int -> int -> + : float * float -> float - - Addition - -> + : string * string -> string - - String concatenation - -> - : int * int -> int -> - : float * float -> float - - Subtraction - -> * : int * int -> int -> * : float * float -> float - - Multiplication - -> / : int * int -> int - - Integer division - -> / : float * float -> float - - Division - -> % : int * int -> int - - Remainder (from integer division) - -_Grammar_ - -NOTE: Since I want to use parentheses to mean "real" parentheses, I use - square brackets for grouping inside of rules. - - ::= * - - ::= - | - | - | - | - | - - ::= = ; - | ( [, ]* ) = ; - - ::= - | _ - - ::= ( ) - - ::= - | - | - | - - ::= -> - - ::= < > - | < [, ]* > - - ::= id - | Any - - ::= int - | float - | bool - | str - | char - | void - - ::= type { * } - | interface { * } - - ::= extends [, ]* - | <: [, ]* - | - - ::= ; - | ( * ) ; - - ::= [, ]* - | - - ::= - | - - ::= struct : - | final struct : - | struct : - extends : - | final struct : - extends : - - ::= class : - | final class : - | class = ( ) ; - | class : - extends : - | final class : - extends : - - - ::= mixin : -> - - | final mixin : -> - - - ::= ( [, ]* ) - | ( ) - - ::= implements [, ]* - | impl [, ]* - | - - ::= { * * } - - ::= { * * * } - - ::= init ; - | init = ; - | = ; - | ( ) - - ::= super( ) ; - - ::= [, ]* - | - - ::= - - ::= [, ]* - | - - ::= = - - ::= export : ; - - ::= [, ]* - - ::= - | as - - ::= - | - | - | #n - | - | = - | - | this - | : - | isa - | if [else ]? - | cond { [ => ;]+ } - | cond { [ => ;]* else ; } - | while - | new : ( ) - | new ( ) - | ! - | - - | || - | && - | == - | != - | ==== - | < - | > - | <= - | >= - | + - | - - | * - | / - | % - | . - | return - | - -NOTE: Here's the precedence and associativity of things above. - Top is most strongly binding, bottom is least. Things on - the same line have same precedence. The : below refers to - casting, and the = is for assignment. else requires a - precedence to avoid shift/reduce errors, even though we - don't have the dangling else problem. - - LEFT | RIGHT | NONASSOC -----------+----------+----------- - . | | - | | ( (function application) - | | #n (tuple selector) - | : isa | - | | !, - (un) - * / % | | - + - | | - | | < <= > >= - | | ==== - == != | | - && | | - || | | - = | | - else | | - | | return - - ::= ( ) - | ( ) - ::= fun ( ) - - ::= [, ]* - | - - ::= - | - | true - | false - | - | - | null - - ::= { } - - ::= - | - | - - ::= = ; - | ( [, ]* ) = ; - - ::= ; - -_Mixin Definitions_ - -Assume a mixin of the following form: - -[final] mixin MixinName( initType1 initArg1, ..., initTypeN initArgN ) : - ParentIFace( superType1 superArg1, ..., superTypeM superArgM ) -> SelfIFace - [implements IFace1, ..., IFaceK] -{ - Member1; ... MemberI; - SuperNew; - MemberI+1; ... MemberJ; - Exports; -} - -This defines a mixin called MixinName. This mixin consumes a class with -selftype ParentIFace and produces one with selftype SelfIFace. The parent class -must have the initialization arguments listed after ParentIFace. These -arguments are supplied by the new class's initialization. The new class -provides interfaces IFace1 through IFaceK for clients and interface SelfIFace -(its selftype) for further mixins. - -The new class introduces the arguments listed after MixinName as well as all -init fields declared in the members (Member1 through MemberJ). All init -arguments, whether declared in the header or the body of the mixin definition, -are both initialization arguments to the new class and fields usable within -the body of the class. Init field declarations in the body may include default -values. All other initialization arguments to the new class are passed on to -its superclass initializer. - -Member definitions include fields, init fields, and methods, and exactly one -call to the superclass initializer; as mentioned above, init arguments are also -implicit field definitions. Export declarations define a mapping from exported -names to internal member names. diff --git a/collects/honu/environment.ss b/collects/honu/environment.ss deleted file mode 100644 index f95a377ddb..0000000000 --- a/collects/honu/environment.ss +++ /dev/null @@ -1,46 +0,0 @@ -(module environment mzscheme - - (require (lib "contract.ss") - (prefix env: (planet "environment.ss" ("cobbe" "environment.plt" 2 1))) - ) - - (provide/contract - [mapping? (any/c . -> . boolean?)] - [empty (-> mapping?)] - [extend (mapping? identifier? any/c . -> . mapping?)] - [contains? (mapping? identifier? . -> . boolean?)] - [lookup (([mapping - (lambda (mapping) - (and (mapping? mapping) - (contains? mapping id)))] - [id identifier?]) - . ->r . any)] - ) - - ;; mapping? : Any -> Boolean - ;; Reports whether a value is a mapping. - (define (mapping? value) - (env:env? value)) - - ;; empty : -> [Mapping X] - ;; Contructs an empty mapping. - (define (empty) - (env:make-empty-env bound-identifier=?)) - - ;; extend : [Mapping X] Identifier X -> [Mapping X] - ;; Adds or shadows an environment binding. - (define (extend mapping id entry) - (env:extend-env (list id) (list entry) mapping)) - - ;; contains? : [Mapping X] Identifier -> Boolean - ;; Reports whether the given key has an entry. - (define (contains? mapping id) - (env:bound? mapping id)) - - ;; lookup : [Mapping X] Identifier -> X - ;; Returns the entry for the given key. - ;; Raises exn:fail:contract if no entry exists. - (define (lookup mapping id) - (env:lookup mapping id)) - - ) diff --git a/collects/honu/examples/BoundedStack-test.ss b/collects/honu/examples/BoundedStack-test.ss deleted file mode 100644 index 3064536e8e..0000000000 --- a/collects/honu/examples/BoundedStack-test.ss +++ /dev/null @@ -1,41 +0,0 @@ -(define (push stack num) - (send stack BoundedStack<%>-push (new IntegerC% [value num]))) - -(define s0 (emptyBoundedStack 5)) -(define s1 (push s0 5)) -(define s2 (push s1 3)) -(define s3 (push s2 10)) -(define s4 (push s3 20)) -(define s5 (push s4 40)) - -(append (map interface? (list List<%> - Stack<%> - BoundedStack<%> - Integer<%>)) - (map class? (list ConsList% - BoundedStackC% - ListStackC% - IntegerC%)) - (map - (lambda (object) - (andmap - (lambda (spec) (is-a? object spec)) - (list Stack<%> BoundedStack<%> BoundedStack<%>))) - (list s0 s1 s2 s3 s4 s5)) - (list - (not (send s0 BoundedStack<%>-isFull '())) - (not (send s1 BoundedStack<%>-isFull '())) - (not (send s2 BoundedStack<%>-isFull '())) - (not (send s3 BoundedStack<%>-isFull '())) - (not (send s4 BoundedStack<%>-isFull '())) - (send s5 BoundedStack<%>-isFull '())) - (list - (let* ([expected (list 5 3 10 20 40)] - [actual (list)]) - (send s5 BoundedStack<%>-foreach - (lambda (int) - (set! actual (cons (send int Integer<%>-value-get 'Dummy) actual)))) - (equal? expected actual)) - (with-handlers ([exn:fail? (lambda (exn) #t)]) - (push s5 50) - #f))) diff --git a/collects/honu/examples/BoundedStack.honu b/collects/honu/examples/BoundedStack.honu deleted file mode 100644 index 92354da5b1..0000000000 --- a/collects/honu/examples/BoundedStack.honu +++ /dev/null @@ -1,345 +0,0 @@ -// -// -// -$@:@ @@ -// @ -@ @ @ -// $: @@@@@ $@$: $@+@ @ @@@ -// -$@$ @ -@ $+ -@ @ *$ -// *$ @ -$@$@ @ @$$ -// @ @ $* @ @ @$$ -// @+ -$ @: :$ @- *@ $* -$ @ -$ -// @:@$- :@@$- -$$-@@ $@$- @@ @@@- -// -// -// -// - -type Stack { - Stack push(Any x); - pop(); - void foreach(Any -> void); -} - -class ListStackC(List list) : Stack impl Stack { - - Stack push(Any x) { - return new ListStackC(list = new ConsList(car = x, cdr = list)); - } - - pop() { - return (new ListStackC(list = list.rest()), list.first()); - } - - void foreach(Any -> void f) { list.foreach(f); } - - export Stack : push, pop, foreach; -} - -Stack emptyStack() { - return new ListStackC(list = new MTList()); -} - -// -// -//@@@@@: @@ @@ -$@:@ @@ -// @ :@ @ @ @ -@ @ @ -// @ -$ $@$ @@ @@ @@:@@: $@:@ -@@$ $@:@ $: @@@@@ $@$: $@+@ @ @@@ -// @@@$ $- -$ @ @ @+ :@ $* *@ $ -$ $* *@ -$@$ @ -@ $+ -@ @ *$ -// @ :$ @ @ @ @ @ @ @ @ @@@@@ @ @ *$ @ -$@$@ @ @$$ -// @ @ @ @ @ @ @ @ @ @ $ @ @ @ @ $* @ @ @$$ -// @ :@ $- -$ @: +@ @ @ $* *@ +: $* *@ @+ -$ @: :$ @- *@ $* -$ @ -$ -//@@@@@: $@$ :@$-@@@@@ @@@ $@:@@ $@@+ $@:@@ @:@$- :@@$- -$$-@@ $@$- @@ @@@- -// -// -// -// - -type BoundedStack <: Stack { - BoundedStack push(Any x); - pop(); - bool isFull(); - int spaceRemaining(); -} - -// space = number of pushes possible on this stack -class BoundedStackC(Stack stack, int space) : BoundedStack impl BoundedStack { - - bool isFull() { return space < 1; } - int spaceRemaining() { return space; } - - BoundedStack push(Any x) { - if(isFull()) { error("Stack is full"); } - else { - return new BoundedStackC(stack = stack.push(x), space = space - 1); - }; - } - - pop() { - (Stack s, Any obj) = stack.pop(); - return (new BoundedStackC(stack = s, space = space + 1), obj); - } - - void foreach(Any -> void f) { stack.foreach(f); } - - export BoundedStack : push, pop, isFull, spaceRemaining, foreach; -} - -BoundedStack emptyBoundedStack(int n) { - return new BoundedStackC(stack = emptyStack(), space = n); -} - -// -// -// +@@@* -// @ @ -// @ @@:@@: @@@@@ -@@$ $@-@@ -@@$ @@-$+ -// @ @+ :@ @ $ -$ $* :@ $ -$ @$ : -// @ @ @ @ @@@@@ @ @ @@@@@ @ -// @ @ @ @ $ @ @ $ @ -// @ @ @ @: :$ +: $* :@ +: @ -// -@@@: @@@ @@@ :@@$- $@@+ $@:@ $@@+ @@@@@ -// -$ -// -@@$ -// -// - -struct IntegerC(int value) : Integer { } - -// -// -// @@@ @ -// @ @ -// @ -@@ :@@+@ @@@@@ -// @ @ @$ -@ @ -// @ @ :@@$- @ -// @ @ @ *@ @ -// @ @ @ @ :@ @: :$ -// @@@@@ @@@@@ $+@@: :@@$- -// -// -// -// - -type List { - - List addToFront(Any); - List addToEnd(Any); - - Any first(); - Any atIndex(int); - Any last(); - - List rest(); - List drop(int); - List take(int); - - List appendToEnd(List); - List appendToFront(List); - - List reverse(); - - int length(); - bool empty(); - - List map(Any -> Any); - Any foldl( -> Any, Any); - Any foldr( -> Any, Any); - List filter(Any -> bool); - void foreach(Any -> void); - -} - -class MTList() : List impl List { - - List add(Any elt) { - return new ConsList(car = elt, cdr = (this : List)); - } - - Any no_elts(int n) { - error("The empty list has no elements!"); - } - - Any no_elt() { - error("The empty list has no elements!"); - } - - List rest() { - error("Cannot get the rest of the empty list!"); - } - - List drop(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to drop elements from an empty list!"); - }; - } - - List take(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to take elements from an empty list!"); - }; - } - - List ret_other(List l) { return l; } - - List reverse() { return (this : List); } - - int length() { return 0; } - - bool empty() { return true; } - - List map(Any -> Any f) { return (this : List); } - - Any fold( -> Any f, Any i) { return i; } - - List filter(Any -> bool f) { return (this : List); } - - void foreach(Any -> void f) { return(); } - - export List : add as addToFront, add as addToEnd, - no_elt as first, no_elts as atIndex, no_elt as last, - rest, drop, take, reverse, - ret_other as appendToEnd, ret_other as appendToFront, - length, empty, - map, fold as foldl, fold as foldr, filter, foreach; -} - -// Since init slots get translated to init fields by need, we can put -// car and cdr here, and then use them appropriately inside the methods -// which will make them fields. -class ConsList(Any car, List cdr) : List impl List { - - Any first() { return car; } - - Any atIndex(int n) { - if n == 0 { - car; - } else { - cdr.atIndex(n - 1); - }; - } - - Any last() { - if cdr.empty() { - car; - } else { - cdr.last(); - }; - } - - List rest() { - return cdr; - } - - List drop(int n) { - if n == 0 { - this : List; - } else { - cdr.drop(n - 1); - }; - } - - List take(int n) { - if n == 0 { - new MTList(); - } else { - new ConsList(car = car, cdr = cdr.take(n - 1)); - }; - } - - List addToFront(Any x) { - return new ConsList(car = x, cdr = (this : List)); - } - - List addToEnd(Any x) { - return new ConsList(car = car, cdr = cdr.addToEnd(x)); - } - - List appendToFront(List other) { - if other.empty() { - this : List; - } else { - new ConsList(car = other.first(), cdr = other.drop(1)); - }; - } - - List appendToEnd(List other) { - return new ConsList(car = car, cdr = cdr.appendToEnd(other)); - } - - List reverse() { - return cdr.reverse().addToEnd(car); - } - - int length() { return 1 + cdr.length(); } - - bool empty() { return false; } - - List map(Any -> Any f) { - return new ConsList(car = f(car), cdr = cdr.map(f)); - } - - Any foldl( -> Any f, Any i) { - return f(car, cdr.foldl(f, i)); - } - - Any foldr( -> Any f, Any i) { - return cdr.foldr(f, f(car, i)); - } - - List filter(Any -> bool f) { - if f(car) { - new ConsList(car = car, cdr = cdr.filter(f)); - } else { - cdr.filter(f); - }; - } - - void foreach(Any -> void f) { - f(car); - cdr.foreach(f); - } - - export List : addToFront, addToEnd, first, atIndex, last, reverse, - rest, drop, take, appendToEnd, appendToFront, length, empty, - map, foldl, foldr, filter, foreach; -} - - -// -// -//@@@@@@ @@ -// @ @ @ -// @ @ @@ @@ $@$: @@+-$: @@:@$- @ -@@$ :@@+@ -// @@@ $ -$- -@ @+@$@ @: -$ @ $ -$ @$ -@ -// @ @ $$- -$@$@ @ @ @ @ @ @ @@@@@ :@@$- -// @ -$$ $* @ @ @ @ @ @ @ $ *@ -// @ @ -$- $ @- *@ @ @ @ @: -$ @ +: @ :@ -//@@@@@@ @@ @@ -$$-@@@@@@@@@ @-@$ @@@@@ $@@+ $+@@: -// @ -// @@@ -// -// - - -// Stack empty = emptyBoundedStack(5); -// Stack s1 = empty.push(new IntegerC(value = 5)); -// Stack s2 = s1.push(new IntegerC(value = 3)); -// Stack s3 = s2.push(new IntegerC(value = 10)); -// Stack s4 = s3.push(new IntegerC(value = 20)); -// Stack s5 = s4.push(new IntegerC(value = 40)); - -// use foreach + don't care(about binding) syntax - -// _ = s5.foreach(void fun(Any x) { -// cond { -// x isa Integer => printLine(intToString((x : Integer).value)); -// else printLine("Unknown type of value"); -// }; -// }); - -// Now try adding something to s5! - -// Stack s6 = s5.push(new IntegerC(value = 50)); diff --git a/collects/honu/examples/EvenOddClass-test.ss b/collects/honu/examples/EvenOddClass-test.ss deleted file mode 100644 index a128add47a..0000000000 --- a/collects/honu/examples/EvenOddClass-test.ss +++ /dev/null @@ -1,8 +0,0 @@ -(define EO (new EvenOddC%)) - -(list (interface? EvenOdd<%>) - (class? EvenOddC%) - (send EO EvenOdd<%>-even 4) - (not (send EO EvenOdd<%>-even 5)) - (send EO EvenOdd<%>-odd 7) - (not (send EO EvenOdd<%>-odd 6))) diff --git a/collects/honu/examples/EvenOddClass.honu b/collects/honu/examples/EvenOddClass.honu deleted file mode 100644 index 7c65aed939..0000000000 --- a/collects/honu/examples/EvenOddClass.honu +++ /dev/null @@ -1,24 +0,0 @@ -type EvenOdd { - bool even(int); - bool odd(int); -} - -// The following class tests mutually recursive methods. - -class EvenOddC() : EvenOdd impl EvenOdd { - bool even(int n) { - cond { - n == 0 => return true; - n < 0 => return even(-n); - else return odd(n - 1); - }; - } - bool odd(int n) { - cond { - n == 0 => return false; - n < 0 => return odd(-n); - else return even(n - 1); - }; - } - export EvenOdd : even, odd; -} diff --git a/collects/honu/examples/List-test.ss b/collects/honu/examples/List-test.ss deleted file mode 100644 index 3148cee6ce..0000000000 --- a/collects/honu/examples/List-test.ss +++ /dev/null @@ -1,19 +0,0 @@ -(define MT (new MTList%)) -(define (Cons first rest) (new ConsList% [car first] [cdr rest])) - -(define l0 MT) -(define l1 (Cons 0 l0)) -(define l2 (Cons 1 l1)) -(define l3 (Cons 2 l2)) - -(list (interface? List<%>) - (class? MTList%) - (class? ConsList%) - (send l0 List<%>-empty '()) - (not (send l1 List<%>-empty '())) - (not (send l2 List<%>-empty '())) - (not (send l3 List<%>-empty '())) - (equal? (send l0 List<%>-length '()) 0) - (equal? (send l1 List<%>-length '()) 1) - (equal? (send l2 List<%>-length '()) 2) - (equal? (send l3 List<%>-length '()) 3)) diff --git a/collects/honu/examples/List.honu b/collects/honu/examples/List.honu deleted file mode 100644 index dcc3639166..0000000000 --- a/collects/honu/examples/List.honu +++ /dev/null @@ -1,185 +0,0 @@ -type List { - - List addToFront(Any); - List addToEnd(Any); - - Any first(); - Any atIndex(int); - Any last(); - - List rest(); - List drop(int); - List take(int); - - List appendToEnd(List); - List appendToFront(List); - - List reverse(); - - int length(); - bool empty(); - - List map(Any -> Any); - Any foldl( -> Any, Any); - Any foldr( -> Any, Any); - List filter(Any -> bool); - void foreach(Any -> void); - -} - -class MTList() : List impl List { - - List add(Any elt) { - return new ConsList(car = elt, cdr = (this : List)); - } - - Any no_elts(int n) { - error("The empty list has no elements!"); - } - - Any no_elt() { - error("The empty list has no elements!"); - } - - List rest() { - error("Cannot get the rest of an empty list!"); - } - - List drop(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to drop elements from an empty list!"); - }; - } - - List take(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to take elements from an empty list!"); - }; - } - - List ret_other(List l) { return l; } - - List reverse() { return (this : List); } - - int length() { return 0; } - - bool empty() { return true; } - - List map(Any -> Any f) { return (this : List); } - - Any fold( -> Any f, Any i) { return i; } - - List filter(Any -> bool f) { return (this : List); } - - void foreach(Any -> void f) { return(); } - - export List : add as addToFront, add as addToEnd, - no_elt as first, no_elts as atIndex, no_elt as last, - rest, drop, take, reverse, - ret_other as appendToEnd, ret_other as appendToFront, - length, empty, - map, fold as foldl, fold as foldr, filter, foreach; -} - -// Since init slots get translated to init fields by need, we can put -// car and cdr here, and then use them appropriately inside the methods -// which will make them fields. -class ConsList(Any car, List cdr) : List impl List { - - Any first() { return car; } - - Any atIndex(int n) { - if n == 0 { - car; - } else { - cdr.atIndex(n - 1); - }; - } - - Any last() { - if cdr.empty() { - car; - } else { - cdr.last(); - }; - } - - List rest() { return cdr; } - - List drop(int n) { - if n == 0 { - this : List; - } else { - cdr.drop(n - 1); - }; - } - - List take(int n) { - if n == 0 { - new MTList(); - } else { - new ConsList(car = car, cdr = cdr.take(n - 1)); - }; - } - - List addToFront(Any x) { - return new ConsList(car = x, cdr = (this : List)); - } - - List addToEnd(Any x) { - return new ConsList(car = car, cdr = cdr.addToEnd(x)); - } - - List appendToFront(List other) { - if other.empty() { - this : List; - } else { - new ConsList(car = other.first(), cdr = other.drop(1)); - }; - } - - List appendToEnd(List other) { - return new ConsList(car = car, cdr = cdr.appendToEnd(other)); - } - - List reverse() { - return cdr.reverse().addToEnd(car); - } - - int length() { return 1 + cdr.length(); } - - bool empty() { return false; } - - List map(Any -> Any f) { - return new ConsList(car = f(car), cdr = cdr.map(f)); - } - - Any foldl( -> Any f, Any i) { - return f(car, cdr.foldl(f, i)); - } - - Any foldr( -> Any f, Any i) { - return cdr.foldr(f, f(car, i)); - } - - List filter(Any -> bool f) { - if f(car) { - new ConsList(car = car, cdr = cdr.filter(f)); - } else { - cdr.filter(f); - }; - } - - void foreach(Any -> void f) { - f(car); - cdr.foreach(f); - } - - export List : addToFront, addToEnd, first, atIndex, last, reverse, - rest, drop, take, appendToEnd, appendToFront, length, empty, - map, foldl, foldr, filter, foreach; -} diff --git a/collects/honu/examples/Y-test.ss b/collects/honu/examples/Y-test.ss deleted file mode 100644 index c303248273..0000000000 --- a/collects/honu/examples/Y-test.ss +++ /dev/null @@ -1,7 +0,0 @@ -(list (interface? T<%>) - (class? Y%) - (= (main 5) 120) - (= ((fix (lambda (f) - (lambda (n) - (if (zero? n) 0 (+ n (f (- n 1))))))) 5) - 15)) diff --git a/collects/honu/examples/Y.honu b/collects/honu/examples/Y.honu deleted file mode 100644 index c3ec36e2ef..0000000000 --- a/collects/honu/examples/Y.honu +++ /dev/null @@ -1,15 +0,0 @@ -int -> int fix( int> -> int -> int f) { - T -> int -> int g = int->int fun(T x) { f(int fun(int y) { x.f(x)(y); }); }; - g (new Y(f = g)); -} - -struct Y(T -> int -> int f) : T { } - -int -> int factorialor(int -> int factorial) { - int fun(int x) { - if(x == 0) { 1; } - else { x * factorial(x - 1); }; - }; -} - -int main(int n) { fix(factorialor)(n); } diff --git a/collects/honu/examples/bind-tup-top-test.ss b/collects/honu/examples/bind-tup-top-test.ss deleted file mode 100644 index aa8d1bf04c..0000000000 --- a/collects/honu/examples/bind-tup-top-test.ss +++ /dev/null @@ -1 +0,0 @@ -(list (= x 3) (= y 4)) diff --git a/collects/honu/examples/bind-tup-top.honu b/collects/honu/examples/bind-tup-top.honu deleted file mode 100644 index 9fcd93a46d..0000000000 --- a/collects/honu/examples/bind-tup-top.honu +++ /dev/null @@ -1 +0,0 @@ -(int x, int y) = { int x = 3; int y = 4; (x, y); }; diff --git a/collects/honu/examples/cond-test-test.ss b/collects/honu/examples/cond-test-test.ss deleted file mode 100644 index 627e1ccb68..0000000000 --- a/collects/honu/examples/cond-test-test.ss +++ /dev/null @@ -1 +0,0 @@ -(list (= x 2)) \ No newline at end of file diff --git a/collects/honu/examples/cond-test.honu b/collects/honu/examples/cond-test.honu deleted file mode 100644 index 7ca2ba873a..0000000000 --- a/collects/honu/examples/cond-test.honu +++ /dev/null @@ -1,5 +0,0 @@ -int x = cond { - 1 > 3 => 4; - 5 < 6 => 2; - else 8; - }; diff --git a/collects/honu/examples/even-odd-test.ss b/collects/honu/examples/even-odd-test.ss deleted file mode 100644 index 7fc5198a58..0000000000 --- a/collects/honu/examples/even-odd-test.ss +++ /dev/null @@ -1,4 +0,0 @@ -(list (even 4) - (not (even 5)) - (not (odd 4)) - (odd 5)) diff --git a/collects/honu/examples/even-odd.honu b/collects/honu/examples/even-odd.honu deleted file mode 100644 index c65e853679..0000000000 --- a/collects/honu/examples/even-odd.honu +++ /dev/null @@ -1,23 +0,0 @@ -// This tests mutually recursive function definitions. - -bool even(int n) { - cond { - n == 0 => return true; - n < 0 => return even(-n); - else return odd(n - 1); - }; -} - -// If the following line is uncommented, loading this file -// should fail because even and odd are no longer considered -// mutually recursive. -// -// _ = null; - -bool odd(int n) { - cond { - n == 0 => return false; - n < 0 => return odd(-n); - else return even(n - 1); - }; -} diff --git a/collects/honu/examples/exprs-test.ss b/collects/honu/examples/exprs-test.ss deleted file mode 100644 index 08011fceec..0000000000 --- a/collects/honu/examples/exprs-test.ss +++ /dev/null @@ -1,19 +0,0 @@ -(define (testfact fact) - (list (= (fact 1) 1) - (= (fact 2) 2) - (= (fact 3) 6) - (= (fact 4) 24) - (= (fact 5) 120))) - -(define (testfib fib) - (list (= (fib 0) 0) - (= (fib 2) 1) - (= (fib 4) 3) - (= (fib 6) 8))) - -(append (testfact fact) - (testfact fact2) - (testfact impfact) - (testfact (lambda (n) (cadr (fibfact n)))) - (testfib fib) - (testfib (lambda (n) (car (fibfact n))))) diff --git a/collects/honu/examples/exprs.honu b/collects/honu/examples/exprs.honu deleted file mode 100644 index e87c5c81e0..0000000000 --- a/collects/honu/examples/exprs.honu +++ /dev/null @@ -1,48 +0,0 @@ -int fact(int n) { - if (n == 0) { return 1; } - else { return n * fact(n - 1); }; -} - - divrem(int x, int y) { - (int a, int b) = (x / y, x % y); - return (a, b); -} - -int impfact(int n) { - int ret = 1; - while(n > 1) { - ret = ret * n; - n = n - 1; - }; - return ret; -} - -int factacc(int n, int a) { - if (n == 0) { return a; } - else { return factacc(n - 1, n * a); }; -} - -int fact2(int n) { - return factacc(n, 1); -} - -int fib_h(int n, int a, int b) { - if(n == 0) { return a; } - else { return fib_h(n - 1, b, a + b); }; -} - -int fib(int n) { - return fib_h(n, 0, 1); -} - - fibfact(int n) { - return (fib(n), fact(n)); -} - -void printFibUpTo(int n) { - int x = 0; - while(x < n) { - printLine(intToString(fib(x))); - x = x + 1; - }; -} \ No newline at end of file diff --git a/collects/honu/examples/old/Character.honu b/collects/honu/examples/old/Character.honu deleted file mode 100644 index 2ef086c625..0000000000 --- a/collects/honu/examples/old/Character.honu +++ /dev/null @@ -1,12 +0,0 @@ -type Character { - char value; - String toString(); -} - -class CharBox() : Character impl Character { - init char value; - - String toString() { return new StrBox(value = charToStr(value)); } - - export Character : value, toString; -} diff --git a/collects/honu/examples/old/Fact-Integer.honu b/collects/honu/examples/old/Fact-Integer.honu deleted file mode 100644 index 31cf77bec6..0000000000 --- a/collects/honu/examples/old/Fact-Integer.honu +++ /dev/null @@ -1,78 +0,0 @@ -type Integer { - int value; - - Integer succ(); - Integer plus(Integer y); - Integer times(Integer y); -} - -type IFact { - Integer fact(); -} - -class Zero() : Integer impl Integer, IFact { - - int value = 0; - - Integer plus(Integer y) { - return y; - } - - Integer times(Integer y) { - return (this : Integer); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - Integer fact() { - return new Positive : Integer(pred = (this : Integer)); - } - - export Integer : value, plus, times, succ; - - export IFact : fact; -} - -class Positive() : Integer impl Integer, IFact { - - init Integer pred; - - int value = pred.value + 1; - - Integer plus(Integer y) { - return pred.plus(y.succ()); - } - - Integer times(Integer y) { - return pred.times(y).plus(y); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - Integer fact() { - return times((pred : IFact).fact()); - } - - export Integer : value, plus, times, succ; - export IFact : fact; -} - -Integer main(){ - Integer zero = new Zero : Integer(); - Integer one = new Positive : Integer(pred = zero); - Integer two = new Positive : Integer(pred = one); - Integer three = one.plus(two); - Integer four = two.times(two); - Integer five = four.plus(one); - Integer six = two.plus(four); - Integer seven = one.plus(two.plus(four)); - Integer eight = two.times(two); - Integer nine = three.times(three); - Integer ten = nine.plus(one); - - return (five : IFact).fact(); -} diff --git a/collects/honu/examples/old/Fact.honu b/collects/honu/examples/old/Fact.honu deleted file mode 100644 index 95a01326a9..0000000000 --- a/collects/honu/examples/old/Fact.honu +++ /dev/null @@ -1,33 +0,0 @@ -type IFact { - int fact(int n); -} - -class FactRec() : IFact impl IFact { - int fact(int n) { - return factA(n, 1); - } - - int factA(int n, int a) { - if n == 0 { a; } - else { factA(n - 1, a * n); }; - } - - export IFact : fact; -} - -class FactAcc() : IFact impl IFact { - int fact(int n) { - int ret = 1; - while (n > 1) { - ret = ret * n; - n = n - 1; - }; - return ret; - } - - export IFact : fact; -} - -int main(){ - (new FactRec:IFact()).fact(500) + (new FactAcc:IFact()).fact(500); -} diff --git a/collects/honu/examples/old/Float.honu b/collects/honu/examples/old/Float.honu deleted file mode 100644 index d910ecb6a3..0000000000 --- a/collects/honu/examples/old/Float.honu +++ /dev/null @@ -1,13 +0,0 @@ -type Float { - float value; - - String toString(); -} - -class FloatBox() : Float impl Float { - init float value; - - String toString() { return new StrBox(value = floatToStr(value)); } - - export Float : value, toString; -} diff --git a/collects/honu/examples/old/Integer-box.honu b/collects/honu/examples/old/Integer-box.honu deleted file mode 100644 index b8338fd0f5..0000000000 --- a/collects/honu/examples/old/Integer-box.honu +++ /dev/null @@ -1,13 +0,0 @@ -type Integer { - int value; - - String toString(); -} - -class IntBox() : Integer impl Integer { - init int value; - - String toString() { return new StrBox(value = intToStr(value)); } - - export Integer : value, toString; -} diff --git a/collects/honu/examples/old/Integer-old.honu b/collects/honu/examples/old/Integer-old.honu deleted file mode 100644 index 5f7fa7b655..0000000000 --- a/collects/honu/examples/old/Integer-old.honu +++ /dev/null @@ -1,58 +0,0 @@ -type Integer { - init(); - - Integer pred; - - Integer succ(); - Integer plus(Integer y); - Integer times(Integer y); -} - -class Zero : Integer imp Integer { - init() { - my.pred = this; - } - - Integer pred; - - Integer plus(Integer y) { - return y; - } - - Integer times(Integer y) { - return this; - } - - Integer succ() { - Integer that = new Positive : Integer(); - that.pred = this; - return that; - } - - export Integer : pred as pred, plus as plus, times as times, succ as succ; -} - -class Positive : Integer imp Integer { - - init() { - my.pred = null; - } - - Integer pred; - - Integer plus(Integer y) { - return pred.plus(y.succ()); - } - - Integer times(Integer y) { - return pred.times(y).plus(y); - } - - Integer succ() { - Integer that = new Positive : Integer(); - that.pred = this; - return that; - } - - export Integer : pred as pred, plus as plus, times as times, succ as succ; -} diff --git a/collects/honu/examples/old/Integer-value.honu b/collects/honu/examples/old/Integer-value.honu deleted file mode 100644 index 3de384b31b..0000000000 --- a/collects/honu/examples/old/Integer-value.honu +++ /dev/null @@ -1,62 +0,0 @@ -type Integer { - int value; - - Integer succ(); - Integer plus(Integer y); - Integer times(Integer y); -} - -class Zero() : Integer impl Integer { - - int value = 0; - - Integer plus(Integer y) { - return y; - } - - Integer times(Integer y) { - return (this : Integer); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - export Integer : value, plus, times, succ; -} - -class Positive() : Integer impl Integer { - - init Integer pred; - - int value = pred.value + 1; - - Integer plus(Integer y) { - return pred.plus(y.succ()); - } - - Integer times(Integer y) { - return pred.times(y).plus(y); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - export Integer : value, plus, times, succ; -} - -Integer main() { - Integer zero = new Zero : Integer(); - Integer one = new Positive : Integer(pred = zero); - Integer two = new Positive : Integer(pred = one); - Integer three = one.plus(two); - Integer four = two.times(two); - Integer five = four.plus(one); - Integer six = two.plus(four); - Integer seven = one.plus(two.plus(four)); - Integer eight = two.times(two); - Integer nine = three.times(three); - - return nine.plus(one); -} diff --git a/collects/honu/examples/old/Integer.honu b/collects/honu/examples/old/Integer.honu deleted file mode 100644 index 10ea18cfd9..0000000000 --- a/collects/honu/examples/old/Integer.honu +++ /dev/null @@ -1,56 +0,0 @@ -type Integer { - Integer succ(); - Integer plus(Integer y); - Integer times(Integer y); -} - -class Zero() : Integer impl Integer { - - Integer plus(Integer y) { - return y; - } - - Integer times(Integer y) { - return (this : Integer); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - export Integer : plus, times, succ; -} - -class Positive() : Integer impl Integer { - - init Integer pred; - - Integer plus(Integer y) { - return pred.plus(y.succ()); - } - - Integer times(Integer y) { - return pred.times(y).plus(y); - } - - Integer succ() { - return new Positive : Integer(pred = (this : Integer)); - } - - export Integer : plus, times, succ; -} - -Integer main() { - Integer zero = new Zero : Integer(); - Integer one = new Positive : Integer(pred = zero); - Integer two = new Positive : Integer(pred = one); - Integer three = one.plus(two); - Integer four = two.times(two); - Integer five = four.plus(one); - Integer six = two.plus(four); - Integer seven = one.plus(two.plus(four)); - Integer eight = two.times(two); - Integer nine = three.times(three); - - return nine.plus(one); -} diff --git a/collects/honu/examples/old/List-main.honu b/collects/honu/examples/old/List-main.honu deleted file mode 100644 index d2c71434f6..0000000000 --- a/collects/honu/examples/old/List-main.honu +++ /dev/null @@ -1,24 +0,0 @@ -List iota(int n) { - List ret = new MTList : List(); - while(n > 0) { - ret = new ConsList : List(car = new Int : IInt(value = n), cdr = ret); - n = n - 1; - }; - return ret; -} - -int main() { - List x = iota(100); - List y = x.map(fun(Any x) { - if(x isa IInt) { - new Int : IInt(value = (x : IInt).value * 2); - } else { - x; - }; - }); - (y.foldl(fun(Any x, Any i) { - if x isa IInt && i isa IInt { - new Int : IInt(value = (x : IInt).value + (i : IInt).value); - } else { i; } ; - }, new Int : IInt(value = 0)) : IInt).value; -} diff --git a/collects/honu/examples/old/List.cm b/collects/honu/examples/old/List.cm deleted file mode 100644 index f8b019ab9e..0000000000 --- a/collects/honu/examples/old/List.cm +++ /dev/null @@ -1,3 +0,0 @@ -"List" ; for List, MTList, ConsList -"struct-test" ; for Int/IInt -"List-main" ; for main diff --git a/collects/honu/examples/old/List.honu b/collects/honu/examples/old/List.honu deleted file mode 100644 index 45738d8bf6..0000000000 --- a/collects/honu/examples/old/List.honu +++ /dev/null @@ -1,177 +0,0 @@ -type List { - - List addToFront(Any); - List addToEnd(Any); - - Any first(); - List rest(); - Any atIndex(int); - Any last(); - - List drop(int); - List take(int); - - List appendToEnd(List); - List appendToFront(List); - - List reverse(); - - int length(); - bool empty(); - - List map([Any] -> Any); - Any foldl([Any, Any] -> Any, Any); - Any foldr([Any, Any] -> Any, Any); - List filter([Any] -> bool); - -} - -class MTList() : List impl List { - - List add(Any elt) { - return new ConsList(car = elt, cdr = (this : List)); - } - - Any no_elts(int n) { - error("The empty list has no elements!"); - } - - Any no_elt() { - error("The empty list has no elements!"); - } - - List rest() { - error("The empty list has no elements!"); - } - - List drop(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to drop elements from an empty list!"); - }; - } - - List take(int n) { - if n == 0 { - this : List; - } else { - error("Attempt to take elements from an empty list!"); - }; - } - - List ret_other(List l) { return l; } - - List reverse() { return (this : List); } - - int length() { return 0; } - - bool empty() { return true; } - - List map([Any] -> Any f) { return (this : List); } - - Any fold([Any, Any] -> Any f, Any i) { return i; } - - List filter([Any] -> bool f) { return (this : List); } - - export List : add as addToFront, add as addToEnd, - no_elt as first, rest, no_elts as atIndex, - no_elt as last, drop, take, reverse, - ret_other as appendToEnd, ret_other as appendToFront, - length, empty, - map, fold as foldl, fold as foldr, filter; -} - -class ConsList() : List impl List { - - init Any car; - init List cdr; - - Any first() { return car; } - - List rest() { return cdr; } - - Any atIndex(int n) { - if n == 0 { - car; - } else { - cdr.atIndex(n - 1); - }; - } - - Any last() { - if cdr.empty() { - car; - } else { - cdr.last(); - }; - } - - List drop(int n) { - if n == 0 { - this : List; - } else { - cdr.drop(n - 1); - }; - } - - List take(int n) { - if n == 0 { - new MTList(); - } else { - new ConsList(car = car, cdr = cdr.take(n - 1)); - }; - } - - List addToFront(Any x) { - return new ConsList(car = x, cdr = (this : List)); - } - - List addToEnd(Any x) { - return new ConsList(car = car, cdr = cdr.addToEnd(x)); - } - - List appendToFront(List other) { - if other.empty() { - this : List; - } else { - new ConsList(car = other.first(), cdr = other.drop(1)); - }; - } - - List appendToEnd(List other) { - return new ConsList(car = car, cdr = cdr.appendToEnd(other)); - } - - List reverse() { - return cdr.reverse().addToEnd(car); - } - - int length() { return 1 + cdr.length(); } - - bool empty() { return false; } - - List map([Any] -> Any f) { - return new ConsList(car = f(car), cdr = cdr.map(f)); - } - - Any foldl([Any, Any] -> Any f, Any i) { - return f(car, cdr.foldl(f, i)); - } - - Any foldr([Any, Any] -> Any f, Any i) { - return cdr.foldr(f, f(car, i)); - } - - List filter([Any] -> bool f) { - if f(car) { - new ConsList(car = car, cdr = cdr.filter(f)); - } else { - cdr.filter(f); - }; - } - - export List : addToFront, addToEnd, first, rest, atIndex, last, reverse, - drop, take, appendToEnd, appendToFront, length, empty, - map, foldl, foldr, filter; -} diff --git a/collects/honu/examples/old/Stack-main.honu b/collects/honu/examples/old/Stack-main.honu deleted file mode 100644 index 920c99e1ce..0000000000 --- a/collects/honu/examples/old/Stack-main.honu +++ /dev/null @@ -1,25 +0,0 @@ -IStack main() { - IStack x = new CountedListStack : IStack(); - IStack y = null; - - x.push(new CharBox : Character(value = '5')); - x.push(new IntBox : Integer(value = 3)); - - y = x.copy(); - - while(!y.empty()) { - Any curr = y.pop(); - - if curr isa Character { - printLine("Got a character"); - } else { - if curr isa Integer { - printLine("Got an integer"); - } else { - printLine("Got something else"); - }; - }; - }; - - x; -} diff --git a/collects/honu/examples/old/Stack.cm b/collects/honu/examples/old/Stack.cm deleted file mode 100644 index d0ceada7de..0000000000 --- a/collects/honu/examples/old/Stack.cm +++ /dev/null @@ -1,7 +0,0 @@ -"List" ; For IList, MTList, and ConsList -"Character" ; For Character and CharBox -"Integer-box" ; For Integer and IntBox -"Float" ; For Float and FloatBox -"String" ; For String and StrBox -"Stack" ; For IStack, ListStack, and CountedListStack -"Stack-main" ; For the main expression diff --git a/collects/honu/examples/old/Stack.honu b/collects/honu/examples/old/Stack.honu deleted file mode 100644 index c5c0195034..0000000000 --- a/collects/honu/examples/old/Stack.honu +++ /dev/null @@ -1,80 +0,0 @@ -type IStack -{ - void push (Any elt); - Any pop(); - bool empty(); - IStack copy(); -} - -class ListStack() : IStack impl IStack { - List stack = new MTList(); - - void push (Any elt) { - stack = new ConsList(car = elt, cdr = stack); - } - - Any pop() { - if stack.empty() { - error("The stack is empty!"); - } else { - Any x = stack.first(); - stack = stack.drop(1); - return x; - }; - } - - bool empty() { - return stack.empty(); - } - - IStack copy() { - List tocopy = stack.reverse(); - IStack newStack = new ListStack(); - while(!tocopy.empty()) { - newStack.push(tocopy.first()); - tocopy = tocopy.drop(1); - }; - return newStack; - } - - export IStack : push, pop, empty, copy; -} - -type ICountedStack <: IStack -{ - int numElements(); -} - -mixin addCount() : ICountedStack at IStack impl ICountedStack -{ - int numElts = 0; - - super(); - - void countedPush(Any elt) - { - numElts = numElts + 1; - push(elt); - } - - Any countedPop() - { - Any x = pop(); - numElts = numElts - 1; - return x; - } - - int getSize() - { - numElts; - } - - export ICountedStack : - countedPush as push, - countedPop as pop, - empty, - copy, // but this isn't a countable stack! - getSize as numElements; -} - -subclass CountedListStack = addCount(ListStack); diff --git a/collects/honu/examples/old/String.honu b/collects/honu/examples/old/String.honu deleted file mode 100644 index 0681924813..0000000000 --- a/collects/honu/examples/old/String.honu +++ /dev/null @@ -1,36 +0,0 @@ -type String { - str value; - - void printStr(); - void printLine(); - Integer strToInt(); - Float strToFloat(); - Integer strLen(); - String substr(int, int); - Character charAt(int); -} - -class StrBox() : String impl String { - init str value; - - void printStr() { printStr(value); } - - void printLine() { printLine(value); } - - Integer strToInt() { return new IntBox(value = strToInt(value)); } - - Float strToFloat() { return new FloatBox(value = strToFloat(value)); } - - Integer strLen() { return new IntBox(value = strLen(value)); } - - String substr(int start, int end) { - return new StrBox(value = substr(value, start, end)); - } - - Character charAt(int i) { - return new CharBox(value = charAt(value, i)); - } - - export String : value, printStr, printLine, strToInt, strToFloat, strLen, - substr, charAt; -} diff --git a/collects/honu/examples/old/Y-new.honu b/collects/honu/examples/old/Y-new.honu deleted file mode 100644 index 4c6c2d7e0b..0000000000 --- a/collects/honu/examples/old/Y-new.honu +++ /dev/null @@ -1,15 +0,0 @@ -int -> int fix( int> -> int -> int f) { - T -> int -> int g = fun(T x) { f(fun(int y) { x.f x y; }); }; - g (new Y(f = g)); -} - -struct Y : T { - init T -> int -> int f; -} - -int factorialor(int -> int factorial) (int x) { - if(x == 0) 1 - else x * factorial(x - 1); -} - -int main(int n) { fix factorialor n; } diff --git a/collects/honu/examples/old/Y.honu b/collects/honu/examples/old/Y.honu deleted file mode 100644 index 93e34205b1..0000000000 --- a/collects/honu/examples/old/Y.honu +++ /dev/null @@ -1,40 +0,0 @@ -// compute the fixpoint of f -[int] -> int fix([[int] -> int] -> [int] -> int f) { - [T] -> [int] -> int g = fun(T x) { - [int] -> int h = fun (int y) { // will become: ((outT(x))(x))(y) - [T] -> [int] -> int g = outT(x); - [int] -> int i = g(x); - return i(y); - }; - return f(h); - }; - return g(inT(g)); -} - -// type T = Y of T -> int -> int - -struct Y() : T { - init [T] -> [int] -> int f; -} - -[T] -> [int] -> int outT(T x) { return x.f; } -T inT([T] -> [int] -> int x) { return new Y(f = x); } - -// ----------------------------------------------------------------------------- - -[int] -> int factorialor([int] -> int factorial) { - return - fun (int x) { - if (x == 0) { - return 1; - } - else { - return x * factorial(x - 1); - }; - }; -} - -int main(int n) { - [int] -> int factorial = fix(factorialor); - return factorial(n); -} diff --git a/collects/honu/examples/old/error-prim.honu b/collects/honu/examples/old/error-prim.honu deleted file mode 100644 index 5c2cd684f3..0000000000 --- a/collects/honu/examples/old/error-prim.honu +++ /dev/null @@ -1,4 +0,0 @@ -int main() { - int x = if true { 3; } else { error("I shouldn't be here!"); }; - x + 4; -} diff --git a/collects/honu/examples/old/field-exp-sub.honu b/collects/honu/examples/old/field-exp-sub.honu deleted file mode 100644 index ad77f8660c..0000000000 --- a/collects/honu/examples/old/field-exp-sub.honu +++ /dev/null @@ -1,24 +0,0 @@ -type t { - int x; -} - -type t2 <: t { - int y; -} - -type contains_t { - t x; -} - -class c() : t2 impl t2 { - init int x; - init int y; - - export t2 : x, y; -} - -class cct() : contains_t impl contains_t { - init t2 x; - - export contains_t : x; -} diff --git a/collects/honu/examples/old/forgot-init.honu b/collects/honu/examples/old/forgot-init.honu deleted file mode 100644 index 13835e393f..0000000000 --- a/collects/honu/examples/old/forgot-init.honu +++ /dev/null @@ -1,12 +0,0 @@ -type t { - int x; -} - -class c(int x) : t impl t { - int y = x; - export t : y as x; -} - -t main() { - new c:t(); -} diff --git a/collects/honu/examples/old/func-test.honu b/collects/honu/examples/old/func-test.honu deleted file mode 100644 index 6678dfac29..0000000000 --- a/collects/honu/examples/old/func-test.honu +++ /dev/null @@ -1,12 +0,0 @@ -int fact(int x) { - int ret = 1; - while(x > 1) { - ret = ret * x; - x = x - 1; - }; - return ret; -} - -int main() { - fact(5); -} diff --git a/collects/honu/examples/old/interpreter-str.honu b/collects/honu/examples/old/interpreter-str.honu deleted file mode 100644 index 719e4721c7..0000000000 --- a/collects/honu/examples/old/interpreter-str.honu +++ /dev/null @@ -1,435 +0,0 @@ -// -*- java -*- - -/* - * General Notes: - * - * 1) we need some sort of error reporting mechanism. Full exceptions - * would be nice, but even a MzScheme-like error primitive would be - * sufficient for now. - * 2) We desperately need some sort of polymorphism -- even Java 1.4 - * style would be an improvement! - * 3) What did we decide w.r.t typing _this_ again? - */ - -/* - * Assumed built-in types, operations - * OCaml-style extensional equality - * null? (or, more generally, intensional equality) - * String (changed to str) - * int - * boolean (changed to bool) - */ - -/* -********************************************************************** -* Infrastructure: sets, lists, etc. -**********************************************************************/ - -type StringList -{ - bool contains(str s); - - // Returns copy of this list with first occurrence of s removed. - // If no s, returns copy of this list. - StringList remove(str s); - - // fold that produces a set. - StringSet setFold(StringSet initial, StringSetOp op); - - bool hasDuplicates(); -} - -type StringSetOp -{ - // invoke this closure. - StringSet run(StringSet accum, str s); -} - -class EmptyStringList() : StringList impl StringList -{ - bool contains(str s) { false; } - StringList remove(str s) { this : StringList; } - - StringSet setFold(StringSet initial, StringSetOp op) { initial; } - - bool hasDuplicates() { false; } - - export StringList : contains, setFold, remove, hasDuplicates; -} - -class ConsStringList(StringList rest) : StringList impl StringList -{ - init str first; - - StringList rest = - if rest == null { - error("ConsStringList.rest null"); - } else { rest; }; - - bool contains(str s) - { - (s == first) || rest.contains(s); - } - - StringList remove(str s) - { - if s == first { rest; } - else { new ConsStringList : StringList - (first = first, - rest = rest.remove(s)); }; - } - - StringSet setFold(StringSet initial, StringSetOp op) - { - rest.setFold(op.run(initial, first), op); - } - - bool hasDuplicates() - { - rest.contains(first) || rest.hasDuplicates(); - } - - export StringList : contains, setFold, remove, hasDuplicates; -} - -class UnionOp() : StringSetOp impl StringSetOp -{ - StringSet run(StringSet accum, str s) - { - accum.singleUnion(s); - } - - export StringSetOp : run; -} - -type StringSet -{ - StringSet singleUnion(str elt); - StringSet union(StringSet rhs); - StringSet subElt(str elt); -} - -class StringSetCls() : StringSet impl StringSet -{ - init StringList contents = new EmptyStringList : StringList(); - // this showed up a bug in the parser where I wasn't adding - // the default expressions to things. This caused problems - // when relying on them (i.e. not giving a contents init arg). - // Fixed. - - // How should this get translated? You have a default value - // for contents so it can't go into the init args in the header, - // but you want an additional check later (hasDuplicates()). - StringList contents = - if contents.hasDuplicates() { - error("StringList.contents must be set"); - } else { contents; }; - - StringSet singleUnion(str elt) - { - if contents.contains(elt) { this : StringSet; } - else { - new StringSetCls : StringSet - (contents = new ConsStringList : StringList(first = elt, - rest = contents)); - }; - } - - StringSet union(StringSet rhs) - { - contents.setFold(rhs, new UnionOp : StringSetOp()); - } - - StringSet subElt(str elt) - { - new StringSetCls : StringSet(contents = contents.remove(elt)); - } - - export StringSet : singleUnion, union, subElt; - // was export StringSetCls, typechecker caught this. -} - -/* -********************************************************************** -* Values -**********************************************************************/ - -type Value -{ - Value apply(Value arg); -} - -class IntValue() : Value impl Value // was class Constant, typechecker caught this - // line 359 was the use of IntValue -{ - init int n; - - Value apply(Value arg) { error("cannot apply a constant"); } - - export Value : apply; -} - -class Closure(Ast body, Env rho) : Value impl Value -{ - init str argName; - Ast body = - if body == null { - error("Closure.body null"); - } else { body; }; - Env rho = - if rho == null { - error("Closure.rho null"); - } else { rho; }; // was else body, Typechecker caught this - - Value apply(Value arg) - { - body.getValue(rho.extend(argName, arg)); - // originally thought this was a bug in the interpreter, - // but it was a bug in the typechecker (did supertype - // checking on method arguments, not subtype checking). Fixed. - } - - export Value : apply; // no export statement, typechecker caught this. -} - -/* - ********************************************************************** - * Types - **********************************************************************/ - -type Type -{ - Type getRange(Type domain); -} - -class IntType() : Type impl Type -{ - Type getRange(Type domain) { error("IntType.getRange"); } - - export Type : getRange; -} - -class ArrowType(Type dom, Type rng) : Type impl Type -{ - Type dom = - if dom == null { - error("ArrowType.dom null"); - } else { dom; }; - Type rng = - if rng == null { - error("ArrowType.rng null"); - } else { rng; }; - - Type getRange(Type domain) - { - // extensional equality - if domain ==== dom { rng; } - else { error("arrowType.getRange: domain mismatch"); }; - } - - export Type : getRange; -} - -/* -********************************************************************** -* Environments -**********************************************************************/ - -type Env -{ - Env extend(str var, Any t); - Any lookup(str var); -} - -class EmptyEnv() : Env impl Env -{ - Env extend(str var, Any t) - { - new RibEnv : Env(id = var, bdg = t, rest = this : Env); - } - - Any lookup(str var) - { - error("unbound id"); - } - - export Env : extend, lookup; -} - -class RibEnv(Any bdg, Env rest) : Env impl Env -{ - init str id; - Any bdg = - if bdg == null { - error("RibEnv.bdg null"); - } else { bdg; }; - Env rest = - if rest == null { - error("RibEnv.rest null"); - } else { rest; }; - - Env extend(str var, Any t) - { - new RibEnv : Env(id = var, bdg = t, rest = this : Env); - } - - Any lookup(str var) - { - if var == id { bdg; } else { rest.lookup(var); }; - } - - export Env : extend, lookup; - // was export TypeEnv, should be Env, typechecker caught this. -} -/* - ********************************************************************** - * ASTS - **********************************************************************/ - -type Ast -{ - StringSet vars(); - StringSet freeVars(); - - Type getType(Env gamma); - Value getValue(Env rho); -} - -class Constant() : Ast impl Ast -{ - init int n; - - StringSet vars() - { - new StringSetCls : StringSet(); - } - - StringSet fv() - { - vars(); - } - - Type getType(Env gamma) - { - new IntType : Type(); - } - - Value getValue(Env rho) - { - new IntValue : Value(n = n); - } - - export Ast : vars, fv as freeVars, getType, getValue; -} - -class Variable() : Ast impl Ast -{ - init str name; - - StringSet vars() - { - StringSet result = new StringSetCls : StringSet(); - result.singleUnion(name); - } - - StringSet fv() { vars(); } - - Type getType(Env gamma) - { - gamma.lookup(name) : Type; - } - - Value getValue(Env rho) - { - rho.lookup(name) : Value; - } - - export Ast : vars, fv as freeVars, getType, getValue; - // last part was erroneously typed "getName" instead of "getValue", - // caught by typechecker. -} - -class Lambda(Ast body, Type argType) : Ast impl Ast -{ - init str argName; - - Ast body = - if body == null { - error("Lambda.body null"); - } else { body; }; - Type argType = - if argType == null { - error("Lambda.argType null"); - } else { argType; }; - - StringSet vars() - { - body.vars(); - } - - StringSet freeVars() - { - body.freeVars().subElt(argName); - // was arg (init field) instead of argName (field). - // typechecker caught this. - } - - Type getType(Env gamma) - { - body.getType(gamma.extend(argName, argType)); - // originally thought this was a bug in the interpreter, - // but it was a bug in the typechecker (did supertype - // checking on method arguments, not subtype checking). Fixed. - } - - Value getValue(Env rho) - { - return new Closure : Value(argName = argName, body = body, rho = rho); - } - - export Ast : vars, freeVars, getType, getValue; -} - -class Application(Ast rator, Ast rand) : Ast impl Ast -{ - Ast rator = - if rator == null { - error("Application.rator null"); - } else { rator; }; - Ast rand = - if rand == null { - error("Application.rand null"); - } else { rand; }; - - StringSet vars() - { - StringSet ratorVars = rator.vars(); - ratorVars.union(rand.vars()); - } - - StringSet fv() - { - StringSet ratorFv = rator.freeVars(); - // rator.freeVars (public name) was rator.fv (private name). - // typechecker caught this (happened below also with rand) - ratorFv.union(rand.freeVars()); - } - - Type getType(Env gamma) - { - Type ratorType = rator.getType(gamma); - ratorType.getRange(rand.getType(gamma)); - } - - Value getValue(Env rho) - { - Value ratorVal = rator.getValue(rho); - ratorVal.apply(rand.getValue(rho)); - // ratorVal.apply was rator.apply, which gave method not found error - // typechecker caught this. - // also, rand.getValue was rand.value. Same error. - // typechecker caught this. - } - - export Ast : vars, fv as freeVars, getType, getValue; -} diff --git a/collects/honu/examples/old/interpreter.honu b/collects/honu/examples/old/interpreter.honu deleted file mode 100644 index 0390d747a9..0000000000 --- a/collects/honu/examples/old/interpreter.honu +++ /dev/null @@ -1,465 +0,0 @@ -// -*- java -*- - -/* - * General Notes: - * - * 1) we need some sort of error reporting mechanism. Full exceptions - * would be nice, but even a MzScheme-like error primitive would be - * sufficient for now. - * 2) We desperately need some sort of polymorphism -- even Java 1.4 - * style would be an improvement! - * 3) What did we decide w.r.t typing _this_ again? - */ - -/* - * Assumed built-in types, operations - * OCaml-style extensional equality - * null? (or, more generally, intensional equality) - * String (changed to str) - * int - * boolean (changed to bool) - */ - -/* -********************************************************************** -* Boxing: str -> String -**********************************************************************/ - -type String { - str val; -} - -/* -********************************************************************** -* Infrastructure: sets, lists, etc. -**********************************************************************/ - -type StringList -{ - bool contains(String s); - - // Returns copy of this list with first occurrence of s removed. - // If no s, returns copy of this list. - StringList remove(String s); - - // fold that produces a set. - StringSet setFold(StringSet initial, StringSetOp op); - - bool hasDuplicates(); -} - -type StringSetOp -{ - // invoke this closure. - StringSet run(StringSet accum, String s); -} - -class EmptyStringList() : StringList impl StringList -{ - bool contains(String s) { false; } - StringList remove(String s) { this : StringList; } - - StringSet setFold(StringSet initial, StringSetOp op) { initial; } - - bool hasDuplicates() { false; } - - export StringList : contains, setFold, remove, hasDuplicates; -} - -class ConsStringList(String init_first, StringList init_rest) : StringList impl StringList -{ - String first = - if(init_first == null) { - error("ConsStringList.init_first null"); - } else { - init_first; - }; - StringList rest = - if init_rest == null { - error("ConsStringList.init_rest null"); - } else { init_rest; }; - - bool contains(String s) - { - (s ==== first) || rest.contains(s); - } - - StringList remove(String s) - { - if s ==== first { - rest; - } else { - new ConsStringList : StringList - (init_first = first, - init_rest = rest.remove(s)); - }; - } - - StringSet setFold(StringSet initial, StringSetOp op) - { - rest.setFold(op.run(initial, first), op); - } - - bool hasDuplicates() - { - rest.contains(first) || rest.hasDuplicates(); - } - - export StringList : contains, setFold, remove, hasDuplicates; -} - -class UnionOp() : StringSetOp impl StringSetOp -{ - StringSet run(StringSet accum, String s) - { - accum.singleUnion(s); - } - - export StringSetOp : run; -} - -type StringSet -{ - StringSet singleUnion(String elt); - StringSet union(StringSet rhs); - StringSet subElt(String elt); -} - -class StringSetCls() : StringSet impl StringSet -{ - init StringList init_contents = new EmptyStringList : StringList(); - // this showed up a bug in the parser where I wasn't adding - // the default expressions to things. This caused problems - // when relying on them (i.e. not giving a contents init arg). - // Fixed. - - // How should this get translated? You have a default value - // for contents so it can't go into the init args in the header, - // but you want an additional check later (hasDuplicates()). - StringList contents = - if init_contents.hasDuplicates() { - error("StringList.contents must be set"); - } else { init_contents; }; - - StringSet singleUnion(String elt) - { - if contents.contains(elt) { - this : StringSet; - } else { - new StringSetCls : StringSet - (init_contents = new ConsStringList : StringList(init_first = elt, - init_rest = contents)); - }; - } - - StringSet union(StringSet rhs) - { - contents.setFold(rhs, new UnionOp : StringSetOp()); - } - - StringSet subElt(String elt) - { - new StringSetCls : StringSet(init_contents = contents.remove(elt)); - } - - export StringSet : singleUnion, union, subElt; - // was export StringSetCls, typechecker caught this. -} - -/* -********************************************************************** -* Values -**********************************************************************/ - -type Value -{ - Value apply(Value arg); -} - -class IntValue() : Value impl Value // was class Constant, typechecker caught this - // line 359 was the use of IntValue -{ - init int init_n; - - Value apply(Value arg) { error("cannot apply a constant"); } - - export Value : apply; -} - -class Closure(String init_argName, Ast init_body, Env init_rho) : Value impl Value -{ - String argName = - if init_argName == null { - error("Closure.argName null"); - } else { init_argName; }; - Ast body = - if init_body == null { - error("Closure.body null"); - } else { init_body; }; - Env rho = - if init_rho == null { - error("Closure.rho null") ; - } else { init_rho; }; // was else body, Typechecker caught this - - Value apply(Value arg) - { - body.getValue(rho.extend(argName, arg)); - // originally thought this was a bug in the interpreter, - // but it was a bug in the typechecker (did supertype - // checking on method arguments, not subtype checking). Fixed. - } - - export Value : apply; // no export statement, typechecker caught this. -} - -/* - ********************************************************************** - * Types - **********************************************************************/ - -type Type -{ - Type getRange(Type domain); -} - -class IntType() : Type impl Type -{ - Type getRange(Type domain) { error("IntType.getRange"); } - - export Type : getRange; -} - -class ArrowType(Type init_dom, Type init_rng) : Type impl Type -{ - Type dom = - if init_dom == null { - error("ArrowType.dom null"); - } else { init_dom; }; - Type rng = - if init_rng == null { - error("ArrowType.rng null"); - } else { init_rng; }; - - Type getRange(Type domain) - { - // extensional equality - if domain ==== dom { rng; } - else { error("arrowType.getRange: domain mismatch"); }; - } - - export Type : getRange; -} - -/* -********************************************************************** -* Environments -**********************************************************************/ - -type Env -{ - Env extend(String var, Any t); - Any lookup(String var); -} - -class EmptyEnv() : Env impl Env -{ - Env extend(String var, Any t) - { - new RibEnv : Env(init_id = var, init_bdg = t, init_rest = this : Env); - } - - Any lookup(String var) - { - error("unbound id"); - } - - export Env : extend, lookup; -} - -class RibEnv(String init_id, Any init_bdg, Env init_rest) : Env impl Env -{ - - String id = - if init_id == null { - error("RibEnv.id null"); - } else { init_id; }; - Any bdg = - if init_bdg == null { - error("RibEnv.bdg null"); - } else { init_bdg; }; - Env rest = - if init_rest == null { - error("RibEnv.rest null"); - } else { init_rest; }; - - Env extend(String var, Any t) - { - new RibEnv : Env(init_id = var, init_bdg = t, init_rest = this : Env); - } - - Any lookup(String var) - { - if var ==== id { bdg; } - else { rest.lookup(var); }; - } - - export Env : extend, lookup; - // was export TypeEnv, should be Env, typechecker caught this. -} -/* - ********************************************************************** - * ASTS - **********************************************************************/ - -type Ast -{ - StringSet vars(); - StringSet freeVars(); - - Type getType(Env gamma); - Value getValue(Env rho); -} - -class Constant() : Ast impl Ast -{ - init int n; - - StringSet vars() - { - new StringSetCls : StringSet(); - } - - StringSet fv() - { - vars(); - } - - Type getType(Env gamma) - { - new IntType : Type(); - } - - Value getValue(Env rho) - { - new IntValue : Value(init_n = n); - } - - export Ast : vars, fv as freeVars, getType, getValue; -} - -class Variable(String init_name) : Ast impl Ast -{ - String name = - if init_name == null { - error("Variable.name null"); - } else { init_name; }; - - StringSet vars() - { - StringSet result = new StringSetCls : StringSet(); - result.singleUnion(name); - } - - StringSet fv() { vars(); } - - Type getType(Env gamma) - { - gamma.lookup(name) : Type; - } - - Value getValue(Env rho) - { - rho.lookup(name) : Value; - } - - export Ast : vars, fv as freeVars, getType, getValue; - // last part was erroneously typed "getName" instead of "getValue", - // caught by typechecker. -} - -class Lambda(String init_arg, Ast init_body, Type init_argType) : Ast impl Ast -{ - String argName = - if init_arg == null { - error("Lambda.argName null"); - } else { init_arg; }; - Ast body = - if init_body == null { - error("Lambda.body null"); - } else { init_body; }; - Type argType = - if init_argType == null { - error("Lambda.argType null"); - } else { init_argType; }; - - StringSet vars() - { - body.vars(); - } - - StringSet freeVars() - { - body.freeVars().subElt(argName); - // was arg (init field) instead of argName (field). - // typechecker caught this. - } - - Type getType(Env gamma) - { - body.getType(gamma.extend(argName, argType)); - // originally thought this was a bug in the interpreter, - // but it was a bug in the typechecker (did supertype - // checking on method arguments, not subtype checking). Fixed. - } - - Value getValue(Env rho) - { - return new Closure : Value(init_argName = argName, init_body = body, init_rho = rho); - } - - export Ast : vars, freeVars, getType, getValue; -} - -class Application(Ast init_rator, Ast init_rand) : Ast impl Ast -{ - Ast rator = - if init_rator == null { - error("Application.rator null"); - } else { init_rator; }; - Ast rand = - if init_rand == null { - error("Application.rand null"); - } else { init_rand; }; - - StringSet vars() - { - StringSet ratorVars = rator.vars(); - ratorVars.union(rand.vars()); - } - - StringSet fv() - { - StringSet ratorFv = rator.freeVars(); - // rator.freeVars (public name) was rator.fv (private name). - // typechecker caught this (happened below also with rand) - ratorFv.union(rand.freeVars()); - } - - Type getType(Env gamma) - { - Type ratorType = rator.getType(gamma); - ratorType.getRange(rand.getType(gamma)); - } - - Value getValue(Env rho) - { - Value ratorVal = rator.getValue(rho); - ratorVal.apply(rand.getValue(rho)); - // ratorVal.apply was rator.apply, which gave method not found error - // typechecker caught this. - // also, rand.getValue was rand.value. Same error. - // typechecker caught this. - } - - export Ast : vars, fv as freeVars, getType, getValue; -} diff --git a/collects/honu/examples/old/lambda-test.honu b/collects/honu/examples/old/lambda-test.honu deleted file mode 100644 index cd4a8e88da..0000000000 --- a/collects/honu/examples/old/lambda-test.honu +++ /dev/null @@ -1,4 +0,0 @@ -int main() { - [int, int] -> int x = fun(int x, int y) { x + y; }; - x(3, 4); -} diff --git a/collects/honu/examples/old/matthias1.honu b/collects/honu/examples/old/matthias1.honu deleted file mode 100644 index 534bb19a49..0000000000 --- a/collects/honu/examples/old/matthias1.honu +++ /dev/null @@ -1,23 +0,0 @@ -type t { - void m(); -} - - class A():t { // no implements necessary - t state = null; - void m() { - state = this; // do we need coercions here? - } - export t : m; - } - -type s <: t { } - - subclass B():s extends A at t { - super(); - // use of m somewhere - void m2 { m(); } - // .: the type of this is s - // .: the assignment of state = this still works - // because s is below t - export s : m2 as m; - } diff --git a/collects/honu/examples/old/matthias2.honu b/collects/honu/examples/old/matthias2.honu deleted file mode 100644 index 245f39b202..0000000000 --- a/collects/honu/examples/old/matthias2.honu +++ /dev/null @@ -1,35 +0,0 @@ -type t { - void m(); -} - - class A():t { // no implements necessary - t state = null; - void m() { - state = (this : t); // do we need coercions here? -- yes! - } - export t : m; - } - -type s <: t { } - -type u { - void m(); -} - - subclass B():s extends A at t implements u { - super(); - // use of m somewhere - void m2() { - m(); - } - // .: the type of this is s - // .: the assignment of state = this still works - // because s is below t - export s : m; - export u : m2 as m; - } - -void main() { - u x = new B:u(); - x.m(); -} diff --git a/collects/honu/examples/old/mdcall-test.honu b/collects/honu/examples/old/mdcall-test.honu deleted file mode 100644 index 2bb1419293..0000000000 --- a/collects/honu/examples/old/mdcall-test.honu +++ /dev/null @@ -1,8 +0,0 @@ -type t { - int md(int); -} - -int main() { - t x = null; - x.md(3); -} diff --git a/collects/honu/examples/old/mdcall-test2.honu b/collects/honu/examples/old/mdcall-test2.honu deleted file mode 100644 index 77ada1c650..0000000000 --- a/collects/honu/examples/old/mdcall-test2.honu +++ /dev/null @@ -1,15 +0,0 @@ -type t { - int md(int); -} - -class c() : t impl t { - int my_md(int x) { - return this.md(x); - } - export t : my_md as md; -} - -int main() { - t x = new c:t(); - x.md(3); -} diff --git a/collects/honu/examples/old/method-exp-sub.honu b/collects/honu/examples/old/method-exp-sub.honu deleted file mode 100644 index aea22af062..0000000000 --- a/collects/honu/examples/old/method-exp-sub.honu +++ /dev/null @@ -1,26 +0,0 @@ -type t { - int x; -} - -type t2 <: t { - int y; -} - -type contains_t { - t x(t2); -} - -class c() : t2 impl t2 { - init int x; - init int y; - - export t2 : x, y; -} - -class cct() : contains_t impl contains_t { - t2 x(t x) { - return new c : t2 (x = x.x, y = x.x); - } - - export contains_t : x; -} diff --git a/collects/honu/examples/old/mixin-init.honu b/collects/honu/examples/old/mixin-init.honu deleted file mode 100644 index f76882dba7..0000000000 --- a/collects/honu/examples/old/mixin-init.honu +++ /dev/null @@ -1,31 +0,0 @@ -/* should parse & type check. */ - -type T -{ - int x; - int y; - int get_x(); -} - -class BaseCls() : T impl T -{ - init int x; - init int y; - int get_x() { x; } - export T : x, y, get_x; -} - -mixin mx() : T at T impl T with int x -{ - init int z; - super(x = 3); - export T : z as x, y as y, get_x as get_x; -} - -subclass DerivedCls = mx(BaseCls); - -int main() { - T t = new DerivedCls : T (y = 4, z = 5); - - t.get_x() + t.x + t.y; // should evaluate to 12 -} diff --git a/collects/honu/examples/old/old-stack.honu b/collects/honu/examples/old/old-stack.honu deleted file mode 100644 index da6a6d63e3..0000000000 --- a/collects/honu/examples/old/old-stack.honu +++ /dev/null @@ -1,98 +0,0 @@ -/* Again, should parse and type-check. */ - -type charList -{ - charList cons(char); - bool isEmpty(); - char car(); - charList cdr(); -} - -final class MTCList() : charList impl charList { - charList cons(char x) { - return new ConsCList : charList (car = x, cdr = (this : charList)); - } - bool isEmpty() { return true; } - char car() { error("There are no elements in the empty list!"); } - charList cdr() { return (this : charList); } - export charList : car, cdr, isEmpty, cons; -} - -final class ConsCList() : charList impl charList { - init char car; - init charList cdr; - charList cons(char x) { - return new ConsCList : charList (car = x, cdr = (this : charList)); - } - bool isEmpty() { return false; } - char car_func() { return car; } - charList cdr_func() { return cdr; } - export charList : car_func as car, cdr_func as cdr, isEmpty, cons; -} - -type stack -{ - char push (char elt); - char pop(); -} - -class listStack() : stack impl stack { - charList stack = new MTCList : charList(); - - char push (char elt) { - stack = stack.cons(elt); - return elt; - } - char pop() { - if stack.isEmpty() { - error("The stack is empty!"); - } else { - char x = stack.car(); - stack = stack.cdr(); - return x; - }; - } - - export stack : push, pop; -} - -type countedStack <: stack -{ - int numElements(); -} - -mixin addCount() : countedStack at stack impl countedStack -{ - int numElts = 0; - - super(); - - char countedPush(char elt) - { - numElts = numElts + 1; - push(elt); - } - - char countedPop() - { - char x = pop(); - numElts = numElts - 1; - return x; - } - - int getSize() - { - numElts; - } - - export countedStack : - countedPush as push, - countedPop as pop, - getSize as numElements; -} - -subclass countedListStack = addCount(listStack); - -char main() { - (new countedListStack : stack()).push('5'); -} diff --git a/collects/honu/examples/old/point.honu b/collects/honu/examples/old/point.honu deleted file mode 100644 index 83eb430e75..0000000000 --- a/collects/honu/examples/old/point.honu +++ /dev/null @@ -1,56 +0,0 @@ -/* Again, should parse and typecheck, though watch out for constructor - * syntax. - */ - -type Point -{ - int x; - int y; -} - -type ColorPoint extends Point -{ - int color; -} - -type MovingPoint extends Point -{ - float dx; - float dy; -} - -class PtClass() : Point implements Point -{ - init int x; - init int y; - - export Point : x as x, y as y; -} - -class ColorPtClass() : ColorPoint implements Point, ColorPoint -{ - /* We should add syntactic sugar for init fields. */ - - init int x; - init int y; - init int color; - - export Point : x as x, y as y; - export ColorPoint : x as x, y as y, color as color; -} - -mixin makeMovingPoint() : MovingPoint at Point impl MovingPoint -{ - init float dx; - init float dy; - super(); - - export MovingPoint : x, y, dx, dy; -} - -subclass MvPtCls = makeMovingPoint(PtClass); -subclass MvClrPtCls = makeMovingPoint(ColorPtClass); - -MovingPoint main() { - new MvClrPtCls : MovingPoint(x = 3, y = 4, color = 42, dx = 0.4, dy = -3.2); -} diff --git a/collects/honu/examples/old/rel-not-prim.honu b/collects/honu/examples/old/rel-not-prim.honu deleted file mode 100644 index 025b7a9d90..0000000000 --- a/collects/honu/examples/old/rel-not-prim.honu +++ /dev/null @@ -1,17 +0,0 @@ -type t1 { - bool x(); -} - -class c() : t1 impl t1 { - bool x() { return true; } - export t1 : x; -} - -bool main() { - t1 x = new c:t1(); - if (1 < 3) && (2.0 >= 1.5) { - !x.x(); - } else { - error("How'd I get here?"); - }; -} diff --git a/collects/honu/examples/old/simple-init.honu b/collects/honu/examples/old/simple-init.honu deleted file mode 100644 index 4785778a10..0000000000 --- a/collects/honu/examples/old/simple-init.honu +++ /dev/null @@ -1,12 +0,0 @@ -type t { - int x; -} - -class c(int x) : t impl t { - int y = x; - export t : y as x; -} - -t main() { - new c:t(x = 5); -} diff --git a/collects/honu/examples/old/square.honu b/collects/honu/examples/old/square.honu deleted file mode 100644 index 1e2e6aa88c..0000000000 --- a/collects/honu/examples/old/square.honu +++ /dev/null @@ -1,38 +0,0 @@ -/* This should parse and type-check correctly. - Note the field initialization in unitSquare: the declaration of the - field x should shadow the init arg x from that point forward, but - of course the RHS of x's declaration should refer to the init arg. -*/ - -type shape -{ - int x; - int y; - int area(); -} - -type square extends shape -{ - int length; -} - -class unitSquare() : shape impl shape, square -{ - init int x; - init int y; - - int x = x; - int y = y; - int size = 1; - - int area() { size * size; } - - export shape : x as x, - y as y, - area as area; - - export square : x as x, - y as y, - area as area, - size as length; -} diff --git a/collects/honu/examples/old/str-float-prim.honu b/collects/honu/examples/old/str-float-prim.honu deleted file mode 100644 index dba0ef9ee8..0000000000 --- a/collects/honu/examples/old/str-float-prim.honu +++ /dev/null @@ -1,4 +0,0 @@ -float main() { - if ("foo" + "bar" == "foobar") { 1.3 + 5.7; } - else { error("Oops!"); } -} diff --git a/collects/honu/examples/old/struct-test.honu b/collects/honu/examples/old/struct-test.honu deleted file mode 100644 index 1f2c8721af..0000000000 --- a/collects/honu/examples/old/struct-test.honu +++ /dev/null @@ -1,3 +0,0 @@ -struct Int() : IInt { - init int value; -} diff --git a/collects/honu/examples/old/sub-bad-init.honu b/collects/honu/examples/old/sub-bad-init.honu deleted file mode 100644 index 2a07005e6a..0000000000 --- a/collects/honu/examples/old/sub-bad-init.honu +++ /dev/null @@ -1,11 +0,0 @@ -type t {} - -class c() : t { init int x; export t; } - -mixin mx() : t at t with int x, int y { - init int z; - super(x = 1, y = 2); - export t; -} - -subclass c2 = mx(c); // should fail thanks to y = 2 above. diff --git a/collects/honu/examples/old/sub-final.honu b/collects/honu/examples/old/sub-final.honu deleted file mode 100644 index f3059ed961..0000000000 --- a/collects/honu/examples/old/sub-final.honu +++ /dev/null @@ -1,7 +0,0 @@ -type t {} - -final class c() : t { init int x; export t; } - -mixin mx() : t at t with int x { init int z; super(x = 1); export t; } - -subclass c2 = mx(c); // should fail because c is final diff --git a/collects/honu/examples/old/subclass-ext.honu b/collects/honu/examples/old/subclass-ext.honu deleted file mode 100644 index 3228e64ab2..0000000000 --- a/collects/honu/examples/old/subclass-ext.honu +++ /dev/null @@ -1,30 +0,0 @@ -type t1 { - int x; - int y; -} - -type t2 <: t1 { - int add(); -} - -class c1() : t1 implements t1 { - init int x; - init int y; - - export t1 : x, y; -} - -subclass c2() : t2 extends c1 at t1 implements t2 with int x, int y { - init int x; - init int y; - - super(x = x, y = y); - - int add() { return x + y; } - - export t2: x, y, add; -} - -int main() { - new c2:t2(x = 4, y = 6).add(); -} diff --git a/collects/honu/examples/old/uminus.honu b/collects/honu/examples/old/uminus.honu deleted file mode 100644 index aa76e619c8..0000000000 --- a/collects/honu/examples/old/uminus.honu +++ /dev/null @@ -1,13 +0,0 @@ -type t1 { - int x(); -} - -class c() : t1 impl t1 { - int x() { return 7; } - export t1 : x; -} - -int main() { - t1 x = new c:t1(); - -x.x(); -} diff --git a/collects/honu/examples/point-test.ss b/collects/honu/examples/point-test.ss deleted file mode 100644 index 8ce2b31953..0000000000 --- a/collects/honu/examples/point-test.ss +++ /dev/null @@ -1,15 +0,0 @@ -(append (map interface? (list MovingPoint<%> - Point3D<%> - Point<%> - ColorPoint<%> - Color<%>)) - (map class? (list ColorC% - Point3DC% - ColorPointC% - ColorMovingPointC% - MovingColorPointC% - PointC% - MovingPointC%)) - (map mixin? (list makeMobile-mixin - addColor-mixin - $Point3DC-mixin))) diff --git a/collects/honu/examples/point.honu b/collects/honu/examples/point.honu deleted file mode 100644 index fd4357c81c..0000000000 --- a/collects/honu/examples/point.honu +++ /dev/null @@ -1,36 +0,0 @@ -struct PointC(int x, int y) : Point { } -struct ColorC(int r, int g, int b) : Color { } - -// Make extends clause look more like the first part of a class/struct, -// where the "with" args come in the same place as the init slots normally. - -struct Point3DC(int z) : Point3D extends PointC() : Point { super(); } - -type ColorPoint <: Point { Color c; } -type MovingPoint <: Point { void movePoint(int, int); } - -// Make mixins look more like functions for classes to classes by -// making their "type" look more like the following: -// -// () -> - -mixin addColor(Color c) : Point() -> ColorPoint impl ColorPoint { - super(); - export ColorPoint : x, y, c; -} -mixin makeMobile() : Point() -> MovingPoint impl MovingPoint { - super(); - void movePoint(int dx, int dy) { - x = x + dx; - y = y + dy; - } - export MovingPoint : x, y, movePoint; -} - -class ColorPointC = addColor(PointC); -class MovingPointC = makeMobile(PointC); - -// only useable as a MovingPoint -class MovingColorPointC = makeMobile(ColorPointC); -// only usable as a ColorPoint -class ColorMovingPointC = addColor(MovingPointC); diff --git a/collects/honu/examples/struct-test.ss b/collects/honu/examples/struct-test.ss deleted file mode 100644 index 5d3c039799..0000000000 --- a/collects/honu/examples/struct-test.ss +++ /dev/null @@ -1,3 +0,0 @@ -(append (map interface? (list Color<%> Posn<%> ColorPosn<%>)) - (map class? (list PosnC% ColorC% ColorPosnC%)) - (map mixin? (list $ColorPosnC-mixin))) diff --git a/collects/honu/examples/struct.honu b/collects/honu/examples/struct.honu deleted file mode 100644 index 9400c1e080..0000000000 --- a/collects/honu/examples/struct.honu +++ /dev/null @@ -1,5 +0,0 @@ -struct PosnC(int x, int y) : Posn { } - -struct ColorC(int r, int g, int b) : Color { } - -struct ColorPosnC(Color c) : ColorPosn extends PosnC() : Posn { super(); } diff --git a/collects/honu/examples/tup-bind-test.ss b/collects/honu/examples/tup-bind-test.ss deleted file mode 100644 index 459e16e4aa..0000000000 --- a/collects/honu/examples/tup-bind-test.ss +++ /dev/null @@ -1,5 +0,0 @@ -(list (interface? T<%>) - (class? C%) - (equal? (f 'dummy) '(dummy dummy)) - (= (send (new C%) T<%>-x-get '()) 3) - (= (send (new C%) T<%>-y-get '()) 3)) diff --git a/collects/honu/examples/tup-bind.honu b/collects/honu/examples/tup-bind.honu deleted file mode 100644 index 22ddd7c403..0000000000 --- a/collects/honu/examples/tup-bind.honu +++ /dev/null @@ -1,6 +0,0 @@ - f(int x) { return (x, x); } - -struct C() : T { - int x = 3; - int y = { (int x, int y) = f(x); x; }; -} diff --git a/collects/honu/examples/types-error.honu b/collects/honu/examples/types-error.honu deleted file mode 100644 index 88d97fb639..0000000000 --- a/collects/honu/examples/types-error.honu +++ /dev/null @@ -1,13 +0,0 @@ -type t1 { - int x; -} - -type t2 { - string x; - int m(int); -} - -type t3 <: t1, t2 { - int y; - int m2(int, int); -} diff --git a/collects/honu/examples/types-test.ss b/collects/honu/examples/types-test.ss deleted file mode 100644 index c13113fd54..0000000000 --- a/collects/honu/examples/types-test.ss +++ /dev/null @@ -1 +0,0 @@ -(map interface? (list t1<%> t2<%> t3<%>)) diff --git a/collects/honu/examples/types.honu b/collects/honu/examples/types.honu deleted file mode 100644 index d9b05ed137..0000000000 --- a/collects/honu/examples/types.honu +++ /dev/null @@ -1,12 +0,0 @@ -type t1 { - int x; -} - -type t2 { - int m(int); -} - -type t3 <: t1, t2 { - int y; - int m2(int, int); -} diff --git a/collects/honu/format.ss b/collects/honu/format.ss deleted file mode 100644 index 73b7274f10..0000000000 --- a/collects/honu/format.ss +++ /dev/null @@ -1,75 +0,0 @@ -(module format mzscheme - - (require (lib "contract.ss") - (lib "list.ss") - (lib "class.ss") - (lib "plt-match.ss") - (only "base.ss" null%) - "ast.ss" - ) - - (provide/contract - [honu-value->string (any/c . -> . string?)] - [honu-type->string (ast:type? . -> . string?)] - ) - - (define (string-append-delimited pre mid post strings) - (string-append - pre - (if (null? strings) - "" - (foldl (lambda (str prefix) - (string-append prefix mid str)) - (car strings) - (cdr strings))) - post)) - - (define (honu-value->string value) - (cond - [(number? value) (format "~a" value)] - [(char? value) (format "'~a'" value)] - [(string? value) (format "~s" value)] - [(boolean? value) (if value "true" "false")] - [(procedure? value) "procedure"] - [(null? value) "()"] - [(list? value) ; Always non-empty - (honu-tuple->string value)] - [(is-a? value null%) "null"] - [(object? value) ; Always non-null - (honu-object->string value)] - [else (error 'honu-value->string "Unknown value ~s" value)])) - - (define (honu-tuple->string tuple) - (string-append-delimited "(" ", " ")" (map honu-value->string tuple))) - - (define (honu-object->string value) - (send value format-class-name)) - - (define (honu-type->string t) - (match t - [(struct ast:type:top (_)) - "(top type / any value)"] - [(struct ast:type:bot (_)) - "(bottom type / no value)"] - [(struct ast:type:primitive (_ name)) - (symbol->string name)] - [(struct ast:type:tuple (_ args)) - (string-append-delimited "tuple(" ", " ")" (map honu-type->string args))] - [(struct ast:type:partial/tuple (_ slot type)) - (format "tuple of size >= ~a where the type in position ~a is ~a" - slot slot (honu-type->string type))] - [(struct ast:type:function (_ arg ret)) - (if (ast:type:function? arg) - (string-append "(" (honu-type->string arg) ") -> " (honu-type->string ret)) - (string-append (honu-type->string arg) " -> " (honu-type->string ret)))] - [(struct ast:type:method (_ disp arg ret)) - (string-append "[" (honu-type->string disp) "] " - (honu-type->string arg) " -> " (honu-type->string ret))] - [(struct ast:type:object:iface (_ name)) - (symbol->string (syntax-e name))] - [(struct ast:type:object:any (_)) - "Any"] - [(struct ast:type:object:null (_)) - "null"])) - - ) diff --git a/collects/honu/honu-context.ss b/collects/honu/honu-context.ss deleted file mode 100644 index d98b1d86bb..0000000000 --- a/collects/honu/honu-context.ss +++ /dev/null @@ -1,4 +0,0 @@ -(module honu-context (lib "base.ss" "honu") - - (provide honu-compile-context) - (define honu-compile-context #'here)) diff --git a/collects/honu/honu-tests.ss b/collects/honu/honu-tests.ss deleted file mode 100644 index 95008cbe4d..0000000000 --- a/collects/honu/honu-tests.ss +++ /dev/null @@ -1,20 +0,0 @@ -(module honu-tests mzscheme - - (require (lib "contract.ss") - (planet "test.ss" ("schematics" "schemeunit.plt" 1 1)) - "private/tests/typechecker-tests.ss" - "private/tests/program-tests.ss" - ) - - (provide/contract [honu-tests test-suite?]) - - ;; honu-tests : TestSuite - ;; Honu Test Suite - (define honu-tests - (make-test-suite - "Honu" - program-tests - typechecker-tests - )) - - ) diff --git a/collects/honu/honu.png b/collects/honu/honu.png deleted file mode 100644 index c5c74d7c95..0000000000 Binary files a/collects/honu/honu.png and /dev/null differ diff --git a/collects/honu/info.ss b/collects/honu/info.ss deleted file mode 100644 index e66ec86f54..0000000000 --- a/collects/honu/info.ss +++ /dev/null @@ -1,5 +0,0 @@ -(module info (lib "infotab.ss" "setup") - (define name "Honu") - (define doc.txt "doc.txt") - (define tools (list (list "tool.ss"))) - (define tool-icons '(("honu.png" "honu")))) diff --git a/collects/honu/parameters.ss b/collects/honu/parameters.ss deleted file mode 100644 index 3c655c8295..0000000000 --- a/collects/honu/parameters.ss +++ /dev/null @@ -1,11 +0,0 @@ -(module parameters mzscheme - - (provide (all-defined)) - - (define current-compile-context (make-parameter #f)) - - ;; tenv and lenv, respectively - (define current-type-environment (make-parameter #f)) - (define current-lexical-environment (make-parameter #f)) - - ) \ No newline at end of file diff --git a/collects/honu/parsers/lex.ss b/collects/honu/parsers/lex.ss deleted file mode 100644 index 428f734bb3..0000000000 --- a/collects/honu/parsers/lex.ss +++ /dev/null @@ -1,276 +0,0 @@ -(module lex mzscheme - (require (lib "lex.ss" "parser-tools") - (prefix : (lib "lex-sre.ss" "parser-tools")) - "../readerr.ss") - - (define-lex-abbrevs - [lex:letter (:or (:/ #\a #\z) (:/ #\A #\Z))] - [lex:digit (:/ #\0 #\9)] - [lex:whitespace (:or #\newline #\return #\tab #\space #\vtab)] - - [lex:keyword (:or "type" "interface" "class" "mixin" "struct" "extends" "final" - "impl" "implements" "init" "export" "as" "at" "with" "fun" - "this" "my" "isa" "int" "bool" "string" "float" "char" "Any" - "while" "if" "cond" "else" "new" "super" "cast" "return")] - [lex:grouping (:or "{" "}" "[" "]" "(" ")")] - [lex:separator (:or "," ":" ";" "=" "." "<:" "->" "=>" "@" "_")] - [lex:operator (:or "!" "||" "&&" "!=" "==" "<" "<=" ">" ">=" "+" "-" "*" "/" "%" "====")] - [lex:selector (:: "#" (:+ lex:digit))] - - [lex:string (:: #\" ;; A quoted string starts with a " - (:* (:or (:~ #\\ #\") ;; and has things in it which are - (:: #\\ any-char))) ;; not "s (but \" is okay) - #\")] ;; and ends with a ". - [lex:character (:: #\' any-char #\')] - [lex:ident (:: (:or lex:letter) (:* (:or #\_ lex:letter lex:digit)))] - [lex:integer (:: (:? #\-) (:+ lex:digit))] - [lex:float (:: (:? #\-) (:: (:+ lex:digit) #\. (:+ lex:digit)))] - [lex:line-comment (:: "//" (:* (:~ #\newline)))]) - - (provide EOF for-prec lex-errors keywords separators operators val-tokens) - - (define-tokens EOF - (EOF)) - - (define-empty-tokens for-prec - (UMINUS)) - - (define-tokens lex-errors - (UNPARSEABLE)) - - (define-tokens keywords - (type interface class mixin struct - extends final impl implements - init export as at with - this my null isa - int bool string float char Any void - if cond else true false while fun - new super cast return)) - - (define-tokens separators - (O_CURLY C_CURLY O_BRACE C_BRACE O_PAREN C_PAREN COMMA COLON SEMI_COLON BINDS DOT SUBTYPE ARROW THICK_ARROW AT USCORE)) - - (define-tokens operators - (NOT OR AND NEQ EQUALS LT LE GT GE PLUS MINUS TIMES DIV MOD CLS_EQ)) - - (define-tokens val-tokens - (character floatnum string-lit integer id selector)) - - (define stx-for-original-property (read-syntax #f (open-input-string "original"))) - - (provide create-src-stx) - (define (create-src-stx val source-name start-pos end-pos) - (datum->syntax-object #f val - (list - source-name - (position-line start-pos) - (position-col start-pos) - (position-offset start-pos) - (- (position-offset end-pos) - (position-offset start-pos))) - stx-for-original-property)) - - (define-syntax (token stx) - (syntax-case stx () - [(_ name val) - (identifier? (syntax name)) - (let ([name (syntax name)]) - (with-syntax ([token-name (datum->syntax-object - name - (string->symbol - (format "token-~a" (syntax-e name))))] - [source-name (datum->syntax-object name 'source-name)] - [start-pos (datum->syntax-object name 'start-pos)] - [end-pos (datum->syntax-object name 'end-pos)]) - (syntax - (token-name - (create-src-stx val source-name start-pos end-pos)))))])) - - (define-syntax (ttoken stx) - (syntax-case stx () - [(_ name) - (identifier? (syntax name)) - (syntax (token name 'name))])) - - (provide generate-honu-lexer) - (define (generate-honu-lexer source-name) - (define honu-lexer - (lexer-src-pos - ;; can we just use lex:keyword somehow? - ["type" (ttoken type)] - ["interface" (ttoken interface)] - ["class" (ttoken class)] - ["mixin" (ttoken mixin)] - ["struct" (ttoken struct)] - ["extends" (ttoken extends)] - ["final" (ttoken final)] - ["impl" (ttoken impl)] - ["implements" (ttoken implements)] - ["init" (ttoken init)] - ["export" (ttoken export)] - ["as" (ttoken as)] - ["at" (ttoken at)] - ["with" (ttoken with)] - ["fun" (ttoken fun)] - ["this" (ttoken this)] - ["my" (ttoken my)] - ["null" (ttoken null)] - ["isa" (ttoken isa)] - ["int" (ttoken int)] - ["bool" (ttoken bool)] - ["string" (ttoken string)] - ["float" (ttoken float)] - ["char" (ttoken char)] - ["Any" (ttoken Any)] - ["void" (ttoken void)] - ["while" (ttoken while)] - ["if" (ttoken if)] - ["cond" (ttoken cond)] - ["else" (ttoken else)] - ["new" (ttoken new)] - ["super" (ttoken super)] - ["cast" (ttoken cast)] - ["return" (ttoken return)] - ["true" (token true #t)] - ["false" (token false #f)] - ["{" (ttoken O_CURLY)] - ["}" (ttoken C_CURLY)] - ["[" (ttoken O_BRACE)] - ["]" (ttoken C_BRACE)] - ["(" (ttoken O_PAREN)] - [")" (ttoken C_PAREN)] - ["," (ttoken COMMA)] - [":" (ttoken COLON)] - [";" (ttoken SEMI_COLON)] - ["->" (ttoken ARROW)] - ["=>" (ttoken THICK_ARROW)] - ["@" (ttoken AT)] - ["_" (token USCORE '_)] - ["=" (token BINDS 'binds)] - ["!=" (token NEQ 'neq)] - ["==" (token EQUALS 'equal)] - ["====" (token CLS_EQ 'cls_eq)] - ["!" (token NOT 'not)] - ["&&" (token AND 'and)] - ["||" (token OR 'or)] - ["<" (token LT 'lt)] - ["<=" (token LE 'le)] - [">" (token GT 'gt)] - [">=" (token GE 'ge)] - ["+" (token PLUS 'plus)] - ["-" (token MINUS 'minus)] - ["*" (token TIMES 'times)] - ["/" (token DIV 'div)] - ["%" (token MOD 'mod)] - ["." (token DOT 'dot)] - ["<:" (token SUBTYPE 'subtype)] - [lex:selector - (token selector (string->number (substring lexeme 1 (string-length lexeme))))] - [lex:ident - (token id (string->symbol lexeme))] - [lex:integer - (token integer (string->number lexeme))] - [lex:float - (token floatnum (string->number lexeme))] - [lex:character - (token character (string-ref lexeme 1))] - [lex:string - (token string-lit (substring lexeme 1 (- (string-length lexeme) 1)))] - [lex:line-comment - (return-without-pos (honu-lexer input-port))] - [(:: #\/ #\*) - (begin (comment-lexer source-name start-pos input-port) ;; Get the rest of the comment... - (return-without-pos (honu-lexer input-port)))] ;; then get the next token. - [(:+ lex:whitespace) - (return-without-pos (honu-lexer input-port))] - [(eof) - (ttoken EOF)] - [any-char (token UNPARSEABLE (string->symbol lexeme))])) - honu-lexer) - - (define comment-lexer - (lambda (source-name first-pos port) - (letrec ([lxr (lexer-src-pos - [(:: #\/ #\*) - (begin (lxr input-port) ;; once for the nested comment - (return-without-pos (lxr input-port)))] ;; now finish out the current one - [(:: #\* #\/) - #f] ;; This will get ignored by the call to comment-lexer (whether nested or no) - [(eof) - (raise-read-error-with-stx - "Unexpected end of file while inside block comment." - (create-src-stx eof source-name first-pos end-pos))] - [(:~) - (return-without-pos (lxr input-port))])]) - (lxr port)))) - - (define (syn-val lex a b c d) - (values lex a b (position-offset c) (position-offset d))) - - (define get-block-comment - (lexer - [(:: #\/ #\*) - (begin (get-block-comment input-port) ;; once for the nested comment - (get-block-comment input-port))] ;; now finish out the current one - [(:: #\* #\/) - end-pos] ;; This will get ignored by the call to comment-lexer (whether nested or no) - [(eof) - end-pos] - [(:~) - (get-block-comment input-port)])) - - (define (colorize-string my-start-pos) - (define lxr - (lexer - [#\" (syn-val "" 'string #f my-start-pos end-pos)] - [(eof) (syn-val "" 'error #f my-start-pos end-pos)] - [(:: #\\ #\") (lxr input-port)] - [any-char (lxr input-port)])) - lxr) - - (provide get-syntax-token) - (define get-syntax-token - (lexer - [lex:keyword - (syn-val lexeme 'keyword #f start-pos end-pos)] - [lex:operator - (syn-val lexeme 'keyword #f start-pos end-pos)] - [lex:selector - (syn-val lexeme 'keyword #f start-pos end-pos)] - - [lex:separator - (syn-val lexeme 'default #f start-pos end-pos)] - - [lex:grouping - (syn-val lexeme 'parenthesis (string->symbol lexeme) start-pos end-pos)] - - [lex:ident - (syn-val lexeme 'identifier #f start-pos end-pos)] - - [(:or "true" "false" "null") - (syn-val lexeme 'literal #f start-pos end-pos)] - [lex:integer - (syn-val lexeme 'literal #f start-pos end-pos)] - [lex:float - (syn-val lexeme 'literal #f start-pos end-pos)] - [lex:character - (syn-val lexeme 'literal #f start-pos end-pos)] - - [#\" - ((colorize-string start-pos) input-port)] - - [(:+ lex:whitespace) - (syn-val lexeme 'whitespace #f start-pos end-pos)] - - [lex:line-comment - (syn-val lexeme 'comment #f start-pos end-pos)] - [(:: #\/ #\*) - (syn-val lexeme 'comment #f start-pos (get-block-comment input-port))] - - [(eof) - (syn-val lexeme 'eof #f start-pos end-pos)] - - [any-char - (syn-val lexeme 'error #f start-pos end-pos)])) - - ) diff --git a/collects/honu/parsers/parse.ss b/collects/honu/parsers/parse.ss deleted file mode 100644 index e0438a190d..0000000000 --- a/collects/honu/parsers/parse.ss +++ /dev/null @@ -1,673 +0,0 @@ -(module parse mzscheme - - (require (lib "yacc.ss" "parser-tools") - "lex.ss" - "../readerr.ss" - "../ast.ss" - "../private/tools/general.ss" - "../private/typechecker/type-utils.ss") - - (define (generate-honu-parser source-name) - (define honu-parser - (parser - (start ) - (end EOF) - (src-pos) - ;; (debug "honu.debug") - ;; (yacc-output "honu.yacc") - ;; Since we have things that can look like x.y.z.w(...), we need to - ;; actually specify a precedence for DOT. There are 3 shift/reduce - ;; conflicts for it, so if that warning is seen, it can be safely - ;; ignored. I don't want to turn off the warnings yet in case this - ;; number increases, which means that I've added additional - ;; conflicts. - (precs (right ARROW) ;; for types - - (nonassoc return) - (left else) ;; for expressions - (left BINDS) - (left OR) - (left AND) - (left NEQ EQUALS) - (nonassoc CLS_EQ) - (nonassoc LT LE GT GE) - (left PLUS MINUS) - (left TIMES DIV MOD) - (nonassoc NOT UMINUS) ;; unary operators - (right COLON isa) - (nonassoc selector) - (left O_PAREN) ;; this gives application a precedence - (left DOT)) - (tokens keywords separators operators val-tokens lex-errors EOF for-prec) - (error (lambda (a b stx start end) - (raise-read-error-with-stx - (format "parse error near ~a" (syntax-e stx)) - stx))) - (grammar - ( - [() - $1]) - ( - [( ) - (if (ast? $1) - (cons $1 $2) - (append $1 $2))] - [() - (list)]) - ( - [() - $1] - [() - $1] - [() - $1] - [() - $1] - [() - $1] - [() - $1]) - - ( - [( BINDS SEMI_COLON) - (make-ast:defn:binding - (create-src-stx 'ast:defn:binding source-name $1-start-pos $4-end-pos) - (list (ast:formal-name $1)) (list (ast:formal-type $1)) $3)] - [(O_PAREN C_PAREN BINDS SEMI_COLON) - (let-values ([(names types) (map-two-values (lambda (f) - (values (ast:formal-name f) - (ast:formal-type f))) - $2)]) - (make-ast:defn:binding - (create-src-stx 'ast:defn:binding source-name $1-start-pos $6-end-pos) - names types $5))]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [( id) - (make-ast:formal - (create-src-stx 'ast:formal source-name $1-start-pos $2-end-pos) - $2 $1)] - [(USCORE) - (make-ast:formal - (create-src-stx 'ast:formal source-name $1-start-pos $1-end-pos) - #f (make-top-type $1))]) - - ( - [( id O_PAREN C_PAREN ) - (make-ast:defn:function - (create-src-stx 'ast:defn:function source-name $1-start-pos $6-end-pos) - $2 $1 $4 $6)]) - - ;; Type definitions and needed parts - - ( - [( id O_CURLY C_CURLY) - (make-ast:defn:iface - (create-src-stx 'ast:defn:iface source-name $1-start-pos $6-end-pos) - $2 $3 $5)]) - ( - [(type) (void)] - [(interface) (void)]) - ( - [(id) - (make-iface-type $1 $1)] - [(Any) - (make-any-type $1)]) - ( - [() - $1] - [(void) - (make-void-type $1)] - [(int) - (make-int-type $1)] - [(bool) - (make-bool-type $1)] - [(float) - (make-float-type $1)] - [(char) - (make-char-type $1)] - [(string) - (make-string-type $1)] - [() - $1] - [( ARROW ) - (make-func-type - (create-src-stx 'honu:func-type source-name $1-start-pos $3-end-pos) - $1 $3)]) - ( - [(LT GT) - (make-tuple-type - (create-src-stx 'ast:type:tuple source-name $1-start-pos $2-end-pos) - (list))] - [(LT GT) - (if (null? (cdr $2)) - (car $2) - (make-tuple-type - (create-src-stx 'ast:type:tuple source-name $1-start-pos $3-end-pos) - $2))]) - ( - [() - (list $1)] - [( COMMA ) - (cons $1 $3)]) - ( - [(extends ) - $2] - [(SUBTYPE ) - $2] - [() - '()]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [() - $1] - [() - (list)]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [( id) - (make-ast:formal - (create-src-stx 'ast:formal source-name $1-start-pos $2-end-pos) - $2 $1)]) - ( - [( ) - (cons $1 $2)] - [( ) - (cons $1 $2)] - [() - (list)]) - ( - [( id SEMI_COLON) - (make-ast:iface/member:field - (create-src-stx 'ast:iface/member:field source-name $1-start-pos $3-end-pos) - $2 $1)]) - ( - [( id O_PAREN C_PAREN SEMI_COLON) - (make-ast:iface/member:method - (create-src-stx 'ast:iface/member:method source-name $1-start-pos $6-end-pos) - $2 $1 $4)]) - ( - [() - $1] - [() - (list)]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [() - $1] - [( id) - $1]) - - ( - [(struct id COLON O_CURLY C_CURLY) - (make-ast:defn:structure - (create-src-stx 'ast:defn:structure source-name $1-start-pos $10-end-pos) - $2 $5 #f $6 $3 $8 $9)] - [(final struct id COLON O_CURLY C_CURLY) - (make-ast:defn:structure - (create-src-stx 'ast:defn:structure source-name $1-start-pos $11-end-pos) - $3 $6 #t $7 $4 $9 $10)] - [(struct id COLON extends id COLON - O_CURLY C_CURLY) - (make-ast:defn:substructure - (create-src-stx 'ast:defn:substructure source-name $1-start-pos $17-end-pos) - $2 $5 $7 $10 #f $11 $3 $8 $14 $13 $15 $16)] - [(final struct id COLON extends id COLON - O_CURLY C_CURLY) - (make-ast:defn:substructure - (create-src-stx 'ast:defn:substructure source-name $1-start-pos $18-end-pos) - $3 $6 $8 $11 #t $12 $4 $9 $15 $14 $16 $17)]) - - ;; Class and subclass definitions and needed parts - - ( - [(class id COLON O_CURLY C_CURLY) - (make-ast:defn:class - (create-src-stx 'ast:defn:class source-name $1-start-pos $10-end-pos) - $2 $5 #f $6 $3 $8 $9)] - [(final class id COLON O_CURLY C_CURLY) - (make-ast:defn:class - (create-src-stx 'ast:defn:class source-name $1-start-pos $11-end-pos) - $3 $6 #t $7 $3 $9 $10)] - [(class id BINDS id O_PAREN id C_PAREN SEMI_COLON) - (make-ast:defn:subclass - (create-src-stx 'ast:defn:subclass source-name $1-start-pos $8-end-pos) - $2 $6 $4)] - [(class id COLON extends id COLON - O_CURLY C_CURLY) - (let ([mixin-name (datum->syntax-object $2 (string->symbol (string-append "$" (symbol->string (syntax-e $2)))) $2)] - [subclass-stx (create-src-stx 'ast:defn:subclass source-name $1-start-pos $17-end-pos)]) - (list (make-ast:defn:mixin subclass-stx mixin-name $5 $10 #f $11 $3 $8 $14 $13 $15 $16) - (make-ast:defn:subclass subclass-stx $2 $7 mixin-name)))] - [(final class id COLON extends id COLON - O_CURLY C_CURLY) - (let ([mixin-name (datum->syntax-object $3 (string->symbol (string-append "$" (symbol->string (syntax-e $3)))))] - [subclass-stx (create-src-stx 'ast:defn:subclass source-name $1-start-pos $18-end-pos)]) - (list (make-ast:defn:mixin subclass-stx mixin-name $6 $10 #t $12 $4 $9 $15 $14 $16 $17) - (make-ast:defn:subclass subclass-stx $3 $8 mixin-name)))]) - - ( - [(impl ) - $2] - [(implements ) - $2] - [() - '()]) - ( - [(O_PAREN C_PAREN) - $2]) - ( - [(at ) - $2] - [(AT ) - $2]) - ( - [( ) - (cons $1 $2)] - [( ) - (cons $1 $2)] - [( ) - (cons $1 $2)] - [() - (list)]) - ( - [( id BINDS SEMI_COLON) - (make-ast:class/member:field - (create-src-stx 'ast:class/member:field source-name $1-start-pos $5-end-pos) - $2 $1 $4)]) - ( - [( id O_PAREN C_PAREN ) - (make-ast:class/member:method - (create-src-stx 'ast:class/member:method source-name $1-start-pos $6-end-pos) - $2 $1 $4 $6)]) - ( - [(init id SEMI_COLON) - (make-ast:class/member:field/formal - (create-src-stx 'ast:class/member:field/formal source-name $1-start-pos $4-end-pos) - $3 $2 #f)] - [(init id BINDS SEMI_COLON) - (make-ast:class/member:field/formal - (create-src-stx 'ast:class/member:field/formal source-name $1-start-pos $4-end-pos) - $3 $2 $5)]) - ( - [( ) - (cons $1 $2)] - [() - (list)]) - ( - [(export COLON SEMI_COLON) - (make-ast:export - (create-src-stx 'ast:export source-name $1-start-pos $5-end-pos) - $2 $4)] - [(export SEMI_COLON) - (make-ast:export - (create-src-stx 'ast:export source-name $1-start-pos $3-end-pos) - $2 (list))]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [(id as id) - (make-ast:export/member - (create-src-stx 'ast:export/member source-name $1-start-pos $3-end-pos) - $1 $3)] - [(id) - (make-ast:export/member - (create-src-stx 'ast:export/member source-name $1-start-pos $1-end-pos) - $1 $1)]) - - ;; Mixin definitions - - ( - [(mixin id COLON ARROW - O_CURLY C_CURLY) - (make-ast:defn:mixin - (create-src-stx 'ast:defn:mixin source-name $1-start-pos $15-end-pos) - $2 $8 $5 #f $9 $3 $6 $12 $11 $13 $14)] - [(final mixin id COLON ARROW - O_CURLY C_CURLY) - (make-ast:defn:mixin - (create-src-stx 'ast:defn:mixin source-name $1-start-pos $16-end-pos) - $3 $9 $6 #t $10 $4 $7 $13 $12 $14 $15)]) - ( - [(with ) - $2] - [() - (list)]) - ( - [(super O_PAREN C_PAREN SEMI_COLON) - (make-ast:super-new - (create-src-stx 'ast:super-new source-name $1-start-pos $4-end-pos) - $3)]) - ( - [() - $1] - [() - (list)]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [(id BINDS ) - (make-ast:named/arg - (create-src-stx 'ast:named/arg source-name $1-start-pos $3-end-pos) - $1 $3)]) - - ;; Expressions - - ( - [(O_CURLY C_CURLY) - (if $2 - $2 - (raise-read-error-with-stx - "Blocks must have at least one expression" - (create-src-stx 'honu:block source-name $1-start-pos $3-end-pos)))]) - ( - [( SEMI_COLON ) - (if $3 - (make-ast:expr:sequence - (create-src-stx 'ast:expr:sequence source-name $1-start-pos $3-end-pos) - (list $1) $3) - $1)] - [( ) - (if $2 - (make-ast:expr:let - (create-src-stx 'ast:expr:let source-name $1-start-pos $2-end-pos) - (list $1) $2) - (raise-read-error-with-stx - "Block must end with an expression" - (create-src-stx 'honu:block source-name $1-start-pos $1-end-pos)))] - [() - #f]) - ( - ;; unary operators - [(selector ) - (make-ast:expr:tuple/select - (create-src-stx 'ast:expr:tuple/select source-name $1-start-pos $2-end-pos) - (syntax-e $1) $2)] - [(MINUS ) - (prec UMINUS) - (make-ast:expr:unary/op - (create-src-stx 'ast:expr:unary/op source-name $1-start-pos $2-end-pos) - 'minus $1 #f $2)] - [(NOT ) - (make-ast:expr:unary/op - (create-src-stx 'ast:expr:unary/op source-name $1-start-pos $2-end-pos) - 'not $1 #f $2)] - ;; binary operators - [( OR ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'or $2 #f $1 $3)] - [( AND ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'and $2 #f $1 $3)] - [( CLS_EQ ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'clseq $2 #f $1 $3)] - [( NEQ ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'neq $2 #f $1 $3)] - [( EQUALS ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'equal $2 #f $1 $3)] - [( LT ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'lt $2 #f $1 $3)] - [( LE ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'le $2 #f $1 $3)] - [( GT ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'gt $2 #f $1 $3)] - [( GE ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'ge $2 #f $1 $3)] - [( PLUS ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'plus $2 #f $1 $3)] - [( MINUS ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'minus $2 #f $1 $3)] - [( TIMES ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'times $2 #f $1 $3)] - [( DIV ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'div $2 #f $1 $3)] - [( MOD ) - (make-ast:expr:binary/op - (create-src-stx 'ast:expr:binary/op source-name $1-start-pos $3-end-pos) - 'mod $2 #f $1 $3)] - ;; member access - [( DOT id) - (make-ast:expr:member - (create-src-stx 'honu-member source-name $1-start-pos $3-end-pos) - $1 #f $3 #f)] - [(my DOT id) - (make-ast:expr:member - (create-src-stx 'ast:expr:member source-name $1-start-pos $3-end-pos) - 'my #f $3 #f)] - [( fun O_PAREN C_PAREN ) - (make-ast:expr:function - (create-src-stx 'ast:expr:function source-name $1-start-pos $6-end-pos) - $1 $4 $6)] - [() - $1] - [(this) - (make-ast:expr:self $1)] - [(id) - (make-ast:expr:var $1 $1)] - [( BINDS ) - (make-ast:expr:assign - (create-src-stx 'ast:expr:assign source-name $1-start-pos $3-end-pos) - $1 $3)] - ;; application - [( ) - (make-ast:expr:apply - (create-src-stx 'ast:expr:apply source-name $1-start-pos $2-end-pos) - $1 $2)] - [(new id COLON O_PAREN C_PAREN) - (make-ast:expr:new - (create-src-stx 'ast:expr:new source-name $1-start-pos $7-end-pos) - $2 $4 $6)] - [(new id O_PAREN C_PAREN) - (make-ast:expr:new - (create-src-stx 'ast:expr:new source-name $1-start-pos $5-end-pos) - $2 #f $4)] - [( COLON ) - (make-ast:expr:cast - (create-src-stx 'ast:expr:cast source-name $1-start-pos $3-end-pos) - $1 $3)] - [( isa ) - (make-ast:expr:isa - (create-src-stx 'ast:expr:isa source-name $1-start-pos $3-end-pos) - $1 $3)] - [(if ) - (make-ast:expr:if - (create-src-stx 'ast:expr:if source-name $1-start-pos $3-end-pos) - $2 $3 #f)] - [(if else ) - (make-ast:expr:if - (create-src-stx 'ast:expr:if source-name $1-start-pos $5-end-pos) - $2 $3 $5)] - [(cond O_CURLY C_CURLY) - (make-ast:expr:cond - (create-src-stx 'ast:expr:cond source-name $1-start-pos $4-end-pos) - (car $3) (cadr $3))] - [(while ) - (make-ast:expr:while - (create-src-stx 'ast:expr:while source-name $1-start-pos $3-end-pos) - $2 $3)] - [() - $1] - [(return ) - (make-ast:expr:return - (create-src-stx 'ast:expr:return source-name $1-start-pos $2-end-pos) - $2)] - [() - $1]) - ( - [(O_PAREN C_PAREN) - (make-ast:expr:tuple - (create-src-stx 'ast:expr:tuple source-name $1-start-pos $2-end-pos) - (list))] - [(O_PAREN C_PAREN) - (if (null? (cdr $2)) - (car $2) - (make-ast:expr:tuple - (create-src-stx 'ast:expr:tuple source-name $1-start-pos $3-end-pos) - $2))]) - ( - [(true) - (make-ast:expr:literal $1 (make-bool-type $1) $1)] - [(false) - (make-ast:expr:literal $1 (make-bool-type $1) $1)] - [(integer) - (make-ast:expr:literal $1 (make-int-type $1) $1)] - [(floatnum) - (make-ast:expr:literal $1 (make-float-type $1) $1)] - [(character) - (make-ast:expr:literal $1 (make-char-type $1) $1)] - [(string-lit) - (make-ast:expr:literal $1 (make-string-type $1) $1)] - [(null) - (make-ast:expr:literal $1 (make-null-type $1) (datum->syntax-object $1 'null-obj $1))]) - ( - [( THICK_ARROW SEMI_COLON ) - (list (cons (make-ast:cond/clause - (create-src-stx 'ast:cond/clause source-name $1-start-pos $4-end-pos) - $1 $3) - (car $5)) - (cadr $5))] - [( THICK_ARROW SEMI_COLON) - (list (list (make-ast:cond/clause - (create-src-stx 'ast:cond/clause source-name $1-start-pos $4-end-pos) - $1 $3)) - #f)] - [(else SEMI_COLON) - (list '() $2)]) - ( - [( COMMA ) - (cons $1 $3)] - [() - (list $1)]) - ( - [( BINDS SEMI_COLON) - (make-ast:defn:binding - (create-src-stx 'ast:defn:binding source-name $1-start-pos $4-end-pos) - (list (ast:formal-name $1)) (list (ast:formal-type $1)) $3)] - [(O_PAREN C_PAREN BINDS SEMI_COLON) - (let-values ([(names types) (map-two-values (lambda (f) - (values (ast:formal-name f) - (ast:formal-type f))) - $2)]) - (make-ast:defn:binding - (create-src-stx 'ast:defn:binding source-name $1-start-pos $6-end-pos) - names types $5))]) - ( - [() - $1] - [() - $1])))) - honu-parser) - - (define (parse-interaction port file) - (let ([lexer (generate-honu-lexer file)] - [parser (cadr (generate-honu-parser file))]) - (port-count-lines! port) - (parser - (lambda () - (lexer port))))) - - (define (parse-port port file) - (let ([lexer (generate-honu-lexer file)] - [parser (car (generate-honu-parser file))]) - (port-count-lines! port) - (parser - (lambda () - (lexer port))))) - - (define (parse-file file) - (with-input-from-file file - (lambda () - (parse-port (current-input-port) - (simplify-path (path->complete-path file)))))) - - (define (parse-stdin) - (parse-port (current-input-port) #f)) - - (define (parse-string string) - (parse-port (open-input-string string) #f)) - - (define (read-cm port) - (let loop ((filenames '()) - (val (read port))) - (if (eof-object? val) - (reverse filenames) - (loop (cons (string-append val ".honu") filenames) - (read port))))) - - (define (parse-group port name) - (let ([filenames (read-cm port)]) - (if (null? filenames) - (list) - (let loop ((filenames filenames) - (defns '())) - (let ((parsed (parse-file - (simplify-path - (path->complete-path (car filenames)))))) - (if (null? (cdr filenames)) - (append parsed defns) - (loop (cdr filenames) - (append parsed defns)))))))) - - (define (parse-group-file dirname filename) - (let ([filenames (call-with-input-file - (string-append dirname "/" filename) - read-cm)]) - (if (null? filenames) - (list) - (let loop ((filenames filenames) - (defns '())) - (let ((parsed (parse-file (string-append dirname "/" - (car filenames))))) - (if (null? (cdr filenames)) - (append parsed defns) - (loop (cdr filenames) - (append parsed defns)))))))) - - (provide parse-file parse-port parse-stdin parse-string parse-group parse-group-file parse-interaction) - ) diff --git a/collects/honu/parsers/post-parsing.ss b/collects/honu/parsers/post-parsing.ss deleted file mode 100644 index 559bb46ec0..0000000000 --- a/collects/honu/parsers/post-parsing.ss +++ /dev/null @@ -1,818 +0,0 @@ -(module post-parsing mzscheme - - (require (lib "list.ss" "srfi" "1") - (lib "plt-match.ss") - (lib "struct.ss") - "../ast.ss" - "../parameters.ss" - "../readerr.ss" - "../tenv.ss" - "../private/tools/general.ss") - - ;;;; Here are descriptions of what each of the three functions herein do: - ;;;; - ;;;; convert-static : converts bareword references to static slots/fields/methods - ;;;; into my. - ;;;; convert-slots : converts init slots that are used in methods or exports into - ;;;; init fields instead. Since everything is exported from a struct, - ;;;; all init slots are converted in those. - ;;;; check-this : checks to make sure that all uses of this that are not before a dot - ;;;; are on the LHS of a cast or isa expression. Else an error is thrown. - ;;;; (also until we resolve the mixin safety issue, uses of this before a - ;;;; dot are wrapped in a cast to the class's/mixin's selftype). - ;;;; We also go ahead and implement the check that this is only used inside - ;;;; a class or mixin form. - ;;;; simplify-ast : converts lets inside lets or seqs inside seqs into a single let or seq. - ;;;; since the current parser generates a new let or seq for every binding - ;;;; or expression inside of a block, this merges them. - - ;;;; convert-static MUST be run before convert-slots. - - ;;;; add-defns-to-tenv (from tenv-utils.ss) must be run before - ;;;; post-parse-program. This means that ast:defn:structure and - ;;;; ast:defn:substructure structures will not appear in the defns, - ;;;; and so we no longer need to cover them. - - (provide post-parse-program post-parse-interaction) - (define (post-parse-program defns) - (convert-slots (convert-static (check-this (simplify-ast defns))))) - - (define (post-parse-interaction ast) - (cond - [(ast:expr? ast) - (convert-static-expression (check-this-expression (simplify-expression ast) #f) '())] - [(ast:defn:binding? ast) - (convert-static-defn (check-this-defn (simplify-defn ast)))])) - -; -; -; @ -; @ @ @ -; $@+@ $@$ @@:@@: @@@ @@@ -@@$ @@-$+ @@@@@ :@@+@ @@@@@ $@$: @@@@@ -@@ $@+@ -; $+ -@ $- -$ @+ :@ $ $ $ -$ @$ : @ @$ -@ @ -@ @ @ $+ -@ -; @ @ @ @ @ +: ++ @@@@@ @ @ @@@@@ :@@$- @ -$@$@ @ @ @ -; @ @ @ @ @ $ $ $ @ @ *@ @ $* @ @ @ @ -; $* -$ $- -$ @ @ $:+ +: @ @: :$ @ :@ @: :$ @- *@ @: :$ @ $* -$ -; $@$- $@$ @@@ @@@ :@ $@@+ @@@@@ :@@$- $+@@: :@@$- -$$-@@ :@@$- @@@@@ $@$- -; -; -; -; - - (define (convert-static defns) - (map convert-static-defn defns)) - - (define (convert-static-defn defn) - (match defn - [(struct ast:defn:iface (_ _ _ _)) - defn] - [(struct ast:defn:class (_ _ _ _ _ inits members _)) - (let-values ([(members _) - (convert-static-members members (map ast:formal-name inits))]) - (copy-struct ast:defn:class defn - [ast:defn:class-members members]))] - [(struct ast:defn:mixin (_ _ _ arg-type _ _ inits _ super-new members-before members-after _)) - (let*-values ([(members-before env) - (convert-static-members members-before (map ast:formal-name inits))] - [(super-new) - (convert-static-super-new super-new env)] - [(env) - (extend-env-with-type-members env arg-type)] - [(members-after _) - (convert-static-members members-after env)]) - (copy-struct ast:defn:mixin defn - [ast:defn:mixin-super-new super-new] - [ast:defn:mixin-pre-members members-before] - [ast:defn:mixin-post-members members-after]))] - [(struct ast:defn:subclass (_ _ _ _)) - defn] - [(struct ast:defn:function (_ _ _ _ _)) - defn] - [(struct ast:defn:binding (_ _ _ _)) - defn])) - - (define (extend-env-with-type-members env type) - (let ([type-entry (get-type-entry type)]) - (fold (lambda (m e) - (cons (tenv:member-name m) e)) - env - (tenv:type-members type-entry)))) - - (define (convert-static-members members env) - (let loop ([members members] - [env env] - [results '()]) - (cond - [(null? members) (values (reverse results) env)] - [(ast:class/member:method? (car members)) - (let-values ([(methods remaining) (span ast:class/member:method? members)]) - (let ([env (append (map ast:class/member-name methods) env)]) - (loop remaining - env - ;; reverse is here just to keep the order - (append (reverse (map (lambda (m) - (convert-static-member m env)) - members)) - results))))] - [else - (let ([name (ast:class/member-name (car members))]) - (loop (cdr members) - (cons name env) - (cons (convert-static-member (car members) env) results)))]))) - - (define (convert-static-member member env) - (match member - [(struct ast:class/member:field/formal (_ name _ value)) - (if value - (copy-struct ast:class/member:field/formal member - [ast:class/member:field/formal-default (convert-static-expression value env)]) - member)] - [(struct ast:class/member:field (_ name _ value)) - (copy-struct ast:class/member:field member - [ast:class/member:field-default (convert-static-expression value env)])] - [(struct ast:class/member:method (_ name _ args body)) - ;; remember to remove lexical bindings! - (let ([env (fold (lambda (name env) - (delete name env bound-identifier=?)) - env (map ast:formal-name args))]) - (copy-struct ast:class/member:method member - [ast:class/member:method-body (convert-static-expression body env)]))])) - - (define (convert-static-super-new snew env) - (match snew - [(struct ast:super-new (_ args)) - (copy-struct ast:super-new snew - [ast:super-new-args (map (lambda (a) - (convert-static-name-arg a env)) - args)])])) - - (define (convert-static-name-arg arg env) - (match arg - [(struct ast:named/arg (_ _ value)) - (copy-struct ast:named/arg arg - [ast:named/arg-actual (convert-static-expression value env)])])) - - (define (convert-static-expression expr env) - (match expr - [(struct ast:expr:self (_)) - expr] - [(struct ast:expr:tuple/select (_ _ arg)) - (copy-struct ast:expr:tuple/select expr - [ast:expr:tuple/select-arg (convert-static-expression arg env)])] - [(struct ast:expr:var (stx name)) - (if (s:member name env bound-identifier=?) - (make-ast:expr:member stx 'my #f name #f) - expr)] - [(struct ast:expr:assign (_ lhs rhs)) - (copy-struct ast:expr:assign expr - [ast:expr:assign-lhs (convert-static-expression lhs env)] - [ast:expr:assign-rhs (convert-static-expression rhs env)])] - [(struct ast:expr:apply (_ func arg)) - (copy-struct ast:expr:apply expr - [ast:expr:apply-func (convert-static-expression func env)] - [ast:expr:apply-arg (convert-static-expression arg env)])] - [(struct ast:expr:literal (_ _ _)) - expr] - [(struct ast:expr:unary/op (_ _ _ _ arg)) - (copy-struct ast:expr:unary/op expr - [ast:expr:unary/op-arg (convert-static-expression arg env)])] - [(struct ast:expr:binary/op (_ _ _ _ larg rarg)) - (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-left (convert-static-expression larg env)] - [ast:expr:binary/op-right (convert-static-expression rarg env)])] - ;; originally forgot to remove the identifiers bound by - ;; the lambda from the environment - [(struct ast:expr:function (_ _ args body)) - (let ([env (fold (lambda (name env) - (delete name env bound-identifier=?)) - env (map ast:formal-name args))]) - (copy-struct ast:expr:function expr - [ast:expr:function-body (convert-static-expression body env)]))] - [(struct ast:expr:if (_ cond then else)) - (copy-struct ast:expr:if expr - [ast:expr:if-test (convert-static-expression cond env)] - [ast:expr:if-then (convert-static-expression then env)] - [ast:expr:if-else (if else (convert-static-expression else env) #f)])] - [(struct ast:expr:cast (_ obj _)) - (copy-struct ast:expr:cast expr - [ast:expr:cast-object (convert-static-expression obj env)])] - [(struct ast:expr:isa (_ obj _)) - (copy-struct ast:expr:isa expr - [ast:expr:isa-object (convert-static-expression obj env)])] - [(struct ast:expr:member (_ 'my _ _ _)) - expr] - [(struct ast:expr:member (_ obj _ _ _)) - (copy-struct ast:expr:member expr - [ast:expr:member-object (convert-static-expression obj env)])] - [(struct ast:expr:new (_ _ _ args)) - (copy-struct ast:expr:new expr - [ast:expr:new-args (map (lambda (a) - (convert-static-name-arg a env)) - args)])] - [(struct ast:expr:while (_ cond body)) - (copy-struct ast:expr:while expr - [ast:expr:while-test (convert-static-expression cond env)] - [ast:expr:while-body (convert-static-expression body env)])] - [(struct ast:expr:cond (_ clauses else)) - (copy-struct ast:expr:cond expr - [ast:expr:cond-clauses (map (lambda (c) - (convert-static-cond-clause c env)) - clauses)] - [ast:expr:cond-else (if else (convert-static-expression else env) #f)])] - [(struct ast:expr:return (_ body)) - (copy-struct ast:expr:return expr - [ast:expr:return-result (convert-static-expression body env)])] - [(struct ast:expr:tuple (_ vals)) - (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems (map (lambda (e) - (convert-static-expression e env)) - vals)])] - [(struct ast:expr:let (_ bindings body)) - (let*-values ([(bindings env) (map-and-fold convert-static-binding env bindings)] - [(body) (convert-static-expression body env)]) - (copy-struct ast:expr:let expr - [ast:expr:let-bindings bindings] - [ast:expr:let-body body]))] - [(struct ast:expr:sequence (_ effects value)) - (let ([effects (map (lambda (e) - (convert-static-expression e env)) - effects)] - [value (convert-static-expression value env)]) - (copy-struct ast:expr:sequence expr - [ast:expr:sequence-statements effects] - [ast:expr:sequence-result value]))])) - - (define (convert-static-binding binding env) - (match binding - [(struct ast:defn:binding (_ names _ value)) - (values - (copy-struct ast:defn:binding binding - [ast:defn:binding-init (convert-static-expression value env)]) - (fold (lambda (name env) - (if name - (delete name env bound-identifier=?) - env)) - env names))])) - - (define (convert-static-cond-clause clause env) - (match clause - [(struct ast:cond/clause (_ pred rhs)) - (copy-struct ast:cond/clause clause - [ast:cond/clause-test (convert-static-expression pred env)] - [ast:cond/clause-result (convert-static-expression rhs env)])])) - - -; -; -; @@ -; @ @ @ -; $@+@ $@$ @@:@@: @@@ @@@ -@@$ @@-$+ @@@@@ :@@+@ @ $@$ @@@@@ :@@+@ -; $+ -@ $- -$ @+ :@ $ $ $ -$ @$ : @ @$ -@ @ $- -$ @ @$ -@ -; @ @ @ @ @ +: ++ @@@@@ @ @ @@@@@ :@@$- @ @ @ @ :@@$- -; @ @ @ @ @ $ $ $ @ @ *@ @ @ @ @ *@ -; $* -$ $- -$ @ @ $:+ +: @ @: :$ @ :@ @ $- -$ @: :$ @ :@ -; $@$- $@$ @@@ @@@ :@ $@@+ @@@@@ :@@$- $+@@: @@@@@ $@$ :@@$- $+@@: -; -; -; -; - - ;; CONVERT-SLOTS ASSUMES THAT CONVERT-STATIC HAS BEEN RUN FIRST, SO THAT WE DON'T HAVE TO WORRY - ;; ABOUT SLOT NAMES BEING CAPTURED BY LEXICAL BINDINGS (AS ALL SLOT ACCESSES SHOULD HAVE BEEN - ;; CONVERTED TO MY.) - - (define (convert-slots defns) - (map convert-slots-defn defns)) - - (define (convert-slots-defn defn) - (match defn - [(struct ast:defn:iface (_ _ _ _)) - defn] - [(struct ast:defn:class (_ _ _ _ _ inits members exports)) - (let* ([env (map ast:formal-name inits)] - [used-slots-members (apply append (map (lambda (m) (convert-slots-member m env)) members))] - [used-slots-exports (apply append (map (lambda (e) (convert-slots-export e env)) exports))] - [used-slots (append used-slots-members used-slots-exports)]) - (let loop ([inits inits] - [kept-inits '()] - [new-fields '()]) - (if (null? inits) - (copy-struct ast:defn:class defn - [ast:defn:class-formals (reverse kept-inits)] - [ast:defn:class-members (append (reverse new-fields) members)]) - (if (s:member (ast:formal-name (car inits)) used-slots bound-identifier=?) - (loop (cdr inits) - kept-inits - (cons (make-ast:class/member:field/formal (ast-syntax (car inits)) - (ast:formal-name (car inits)) - (ast:formal-type (car inits)) - #f) - new-fields)) - (loop (cdr inits) - (cons (car inits) kept-inits) - new-fields)))))] - [(struct ast:defn:mixin (_ _ _ _ _ _ inits _ _ members-before members-after exports)) - (let* ([env (map ast:formal-name inits)] - [used-slots-before (apply append (map (lambda (m) (convert-slots-member m env)) members-before))] - [used-slots-after (apply append (map (lambda (m) (convert-slots-member m env)) members-after))] - [used-slots-exports (apply append (map (lambda (e) (convert-slots-export e env)) exports))] - [used-slots (append used-slots-before used-slots-after used-slots-exports)]) - (let loop ([inits inits] - [kept-inits '()] - [new-fields '()]) - (if (null? inits) - (copy-struct ast:defn:mixin defn - [ast:defn:mixin-formals (reverse kept-inits)] - [ast:defn:mixin-pre-members (append (reverse new-fields) members-before)]) - (if (s:member (ast:formal-name (car inits)) used-slots bound-identifier=?) - (loop (cdr inits) - kept-inits - (cons (make-ast:class/member:field/formal (ast-syntax (car inits)) - (ast:formal-name (car inits)) - (ast:formal-type (car inits)) - #f) - new-fields)) - (loop (cdr inits) - (cons (car inits) kept-inits) - new-fields)))))] - [(struct ast:defn:subclass (_ _ _ _)) - defn] - [(struct ast:defn:function (_ _ _ _ _)) - defn] - [(struct ast:defn:binding (_ _ _ _)) - defn])) - - (define (convert-slots-member member env) - (match member - ;; init fields and fields do not necessitate converting init slots into init fields - [(struct ast:class/member:field/formal (_ name _ value)) - (list)] - [(struct ast:class/member:field (_ name _ value)) - (list)] - ;; methods do, though. - [(struct ast:class/member:method (_ name _ _ body)) - (convert-slots-expression body env)])) - - (define (convert-slots-export export env) - (match export - [(struct ast:export (_ _ binds)) - (filter (lambda (old) - (s:member old env bound-identifier=?)) - (map ast:export/member-internal binds))])) - - (define (convert-slots-name-arg arg env) - (match arg - [(struct ast:named/arg (_ _ value)) - (convert-slots-expression value env)])) - - (define (convert-slots-expression expr env) - (match expr - [(struct ast:expr:self (_)) - (list)] - [(struct ast:expr:tuple/select (_ _ arg)) - (convert-slots-expression arg env)] - [(struct ast:expr:var (_ _)) - (list)] - [(struct ast:expr:assign (_ lhs rhs)) - (append (convert-slots-expression lhs env) - (convert-slots-expression rhs env))] - [(struct ast:expr:apply (_ func arg)) - (append (convert-slots-expression func env) - (convert-slots-expression arg env))] - [(struct ast:expr:literal (_ _ _)) - (list)] - [(struct ast:expr:unary/op (_ _ _ _ arg)) - (convert-slots-expression arg env)] - [(struct ast:expr:binary/op (_ _ _ _ larg rarg)) - (append (convert-slots-expression larg env) - (convert-slots-expression rarg env))] - [(struct ast:expr:function (_ _ _ body)) - (convert-slots-expression body env)] - [(struct ast:expr:if (_ cond then else)) - (append (convert-slots-expression cond env) - (convert-slots-expression then env) - (if else (convert-slots-expression else env) (list)))] - [(struct ast:expr:cast (_ obj _)) - (convert-slots-expression obj env)] - [(struct ast:expr:isa (_ obj _)) - (convert-slots-expression obj env)] - [(struct ast:expr:member (_ 'my _ name _)) - (cond - ;; if this is a (bare-referenced) init slot, - ;; then we return a "set" of it, else we return - ;; an empty "set" - [(s:member name env bound-identifier=?) - => - (lambda (l) (list (car l)))] - [else (list)])] - [(struct ast:expr:member (_ obj _ _ _)) - (convert-slots-expression obj env)] - [(struct ast:expr:new (_ _ _ args)) - (apply append - (map (lambda (a) - (convert-slots-name-arg a env)) - args))] - [(struct ast:expr:while (_ cond body)) - (append (convert-slots-expression cond env) - (convert-slots-expression body env))] - [(struct ast:expr:cond (_ clauses else)) - (apply append (cons (if else (convert-slots-expression else env) (list)) - (map (lambda (c) - (convert-slots-cond-clause c env)) - clauses)))] - [(struct ast:expr:return (_ body)) - (convert-slots-expression body env)] - [(struct ast:expr:tuple (_ vals)) - (apply append - (map (lambda (e) - (convert-slots-expression e env)) - vals))] - [(struct ast:expr:let (_ bindings body)) - (let ([bindings (map (lambda (b) - (convert-slots-binding b env)) - bindings)] - [body (convert-slots-expression body env)]) - (apply append (cons body bindings)))] - [(struct ast:expr:sequence (_ effects value)) - (apply append (cons (convert-slots-expression value env) - (map (lambda (e) - (convert-slots-expression e env)) - effects)))])) - - (define (convert-slots-binding binding env) - (match binding - [(struct ast:defn:binding (_ _ _ value)) - (convert-slots-expression value env)])) - - (define (convert-slots-cond-clause clause env) - (match clause - [(struct ast:cond/clause (_ pred rhs)) - (append (convert-slots-expression pred env) - (convert-slots-expression rhs env))])) - - -; -; -; @@ @@ @@ @ -; @ @ @ @ -; $@+@ @-@@: -@@$ $@+@ @ @@@ @@@@@ @-@@: -@@ :@@+@ -; $+ -@ @+ :@ $ -$ $+ -@ @ *$ @ @+ :@ @ @$ -@ -; @ @ @ @@@@@ @ @$$ @@@@@ @ @ @ @ :@@$- -; @ @ @ $ @ @$$ @ @ @ @ *@ -; $* -$ @ @ +: $* -$ @ -$ @: :$ @ @ @ @ :@ -; $@$- @@@ @@@ $@@+ $@$- @@ @@@- :@@$-@@@ @@@ @@@@@ $+@@: -; -; -; -; - - (define (check-this defns) - (map check-this-defn defns)) - - (define (check-this-defn defn) - (match defn - [(struct ast:defn:iface (_ _ _ _)) - defn] - [(struct ast:defn:class (_ _ type _ _ _ members _)) - (let ([members (map (lambda (m) (check-this-member m type)) members)]) - (copy-struct ast:defn:class defn - [ast:defn:class-members members]))] - [(struct ast:defn:mixin (_ _ type _ _ _ _ _ super-new members-before members-after _)) - (let ([members-before (map (lambda (m) (check-this-member m type)) members-before)] - [super-new (check-this-super-new super-new type)] - [members-after (map (lambda (m) (check-this-member m type)) members-after)]) - (copy-struct ast:defn:mixin defn - [ast:defn:mixin-super-new super-new] - [ast:defn:mixin-pre-members members-before] - [ast:defn:mixin-post-members members-after]))] - [(struct ast:defn:subclass (_ _ _ _)) - defn] - [(struct ast:defn:function (_ _ _ _ body)) - ;; we only use check-this-expression here for side-effects (we should not get - ;; a changed AST if this passes, only an exception if the this keyword occurs here). - (begin - (check-this-expression body #f) - defn)] - [(struct ast:defn:binding (_ _ _ rhs)) - ;; same check as in ast:defn:function. - (begin - (check-this-expression rhs #f) - defn)])) - - (define (check-this-member member type) - (match member - [(struct ast:class/member:field/formal (_ name _ value)) - (if value - (copy-struct ast:class/member:field/formal member - [ast:class/member:field/formal-default (check-this-expression value type)]) - member)] - [(struct ast:class/member:field (_ name _ value)) - (copy-struct ast:class/member:field member - [ast:class/member:field-default (check-this-expression value type)])] - [(struct ast:class/member:method (_ name _ args body)) - (copy-struct ast:class/member:method member - [ast:class/member:method-body (check-this-expression body type)])])) - - (define (check-this-super-new snew type) - (match snew - [(struct ast:super-new (_ args)) - (copy-struct ast:super-new snew - [ast:super-new-args (map (lambda (a) - (check-this-name-arg a type)) - args)])])) - - (define (check-this-name-arg arg type) - (match arg - [(struct ast:named/arg (_ _ value)) - (copy-struct ast:named/arg arg - [ast:named/arg-actual (check-this-expression value type)])])) - - (define (check-this-expression expr type) - (match expr - [(struct ast:expr:self (stx)) - (if type - (raise-read-error-with-stx - "Unprotected use of this in a client context" - stx) - (raise-read-error-with-stx - "Use of this keyword found outside of a class or mixin" - stx))] - [(struct ast:expr:tuple/select (_ _ arg)) - (copy-struct ast:expr:tuple/select expr - [ast:expr:tuple/select-arg (check-this-expression arg type)])] - [(struct ast:expr:var (_ _)) - expr] - [(struct ast:expr:assign (_ lhs rhs)) - (copy-struct ast:expr:assign expr - [ast:expr:assign-lhs (check-this-expression lhs type)] - [ast:expr:assign-rhs (check-this-expression rhs type)])] - [(struct ast:expr:apply (_ func arg)) - (copy-struct ast:expr:apply expr - [ast:expr:apply-func (check-this-expression func type)] - [ast:expr:apply-arg (check-this-expression arg type)])] - [(struct ast:expr:literal (_ _ _)) - expr] - [(struct ast:expr:unary/op (_ _ _ _ arg)) - (copy-struct ast:expr:unary/op expr - [ast:expr:unary/op-arg (check-this-expression arg type)])] - [(struct ast:expr:binary/op (_ _ _ _ larg rarg)) - (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-left (check-this-expression larg type)] - [ast:expr:binary/op-right (check-this-expression rarg type)])] - [(struct ast:expr:function (_ _ _ body)) - (copy-struct ast:expr:function expr - [ast:expr:function-body (check-this-expression body type)])] - [(struct ast:expr:if (_ cond then else)) - (copy-struct ast:expr:if expr - [ast:expr:if-test (check-this-expression cond type)] - [ast:expr:if-then (check-this-expression then type)] - [ast:expr:if-else (if else (check-this-expression else type) #f)])] - [(struct ast:expr:cast (_ obj _)) - (if (ast:expr:self? obj) - (if type - expr - (raise-read-error-with-stx - "Use of this keyword found outside of a class or mixin" - (ast-syntax obj))) - (copy-struct ast:expr:cast expr - [ast:expr:cast-object (check-this-expression obj type)]))] - [(struct ast:expr:isa (_ obj _)) - (if (ast:expr:self? obj) - (if type - expr - (raise-read-error-with-stx - "Use of this keyword found outside of a class or mixin" - (ast-syntax obj))) - (copy-struct ast:expr:isa expr - [ast:expr:isa-object (check-this-expression obj type)]))] - [(struct ast:expr:member (_ 'my _ _ _)) - expr] - [(struct ast:expr:member (_ obj _ _ _)) - (if (ast:expr:self? obj) - (if type - ;; to deal with the fact that mixins can mess up the selftype - ;; property, we hack by creating casts in this case. - (copy-struct ast:expr:member expr - [ast:expr:member-object (make-ast:expr:cast (ast-syntax obj) - obj - type)]) - (raise-read-error-with-stx - "Use of this keyword found outside of a class or mixin" - (ast-syntax obj))) - (copy-struct ast:expr:member expr - [ast:expr:member-object (check-this-expression obj type)]))] - [(struct ast:expr:new (_ _ _ args)) - (copy-struct ast:expr:new expr - [ast:expr:new-args (map (lambda (a) - (check-this-name-arg a type)) - args)])] - [(struct ast:expr:while (_ cond body)) - (copy-struct ast:expr:while expr - [ast:expr:while-test (check-this-expression cond type)] - [ast:expr:while-body (check-this-expression body type)])] - [(struct ast:expr:cond (_ clauses else)) - (copy-struct ast:expr:cond expr - [ast:expr:cond-clauses (map (lambda (c) - (check-this-cond-clause c type)) - clauses)] - [ast:expr:cond-else (if else (check-this-expression else type) #f)])] - [(struct ast:expr:return (_ body)) - (copy-struct ast:expr:return expr - [ast:expr:return-result (check-this-expression body type)])] - [(struct ast:expr:tuple (_ vals)) - (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems (map (lambda (e) - (check-this-expression e type)) - vals)])] - [(struct ast:expr:let (_ bindings body)) - (let ([bindings (map (lambda (b) - (check-this-binding b type)) - bindings)] - [body (check-this-expression body type)]) - (copy-struct ast:expr:let expr - [ast:expr:let-bindings bindings] - [ast:expr:let-body body]))] - [(struct ast:expr:sequence (_ effects value)) - (let ([effects (map (lambda (e) - (check-this-expression e type)) - effects)] - [value (check-this-expression value type)]) - (copy-struct ast:expr:sequence expr - [ast:expr:sequence-statements effects] - [ast:expr:sequence-result value]))])) - - (define (check-this-binding binding type) - (match binding - [(struct ast:defn:binding (_ names _ value)) - (copy-struct ast:defn:binding binding - [ast:defn:binding-init (check-this-expression value type)])])) - - (define (check-this-cond-clause clause type) - (match clause - [(struct ast:cond/clause (_ pred rhs)) - (copy-struct ast:cond/clause clause - [ast:cond/clause-test (check-this-expression pred type)] - [ast:cond/clause-result (check-this-expression rhs type)])])) - - -; -; -; @ @@ @ :@@$ -; @ @: @ -; :@@+@ -@@ @@+-$: @@:@$- @ -@@ @@@@@ @@@ @@@ $@$: :@@+@ @@@@@ -; @$ -@ @ @+@$@ @: -$ @ @ @ $- $- -@ @$ -@ @ -; :@@$- @ @ @ @ @ @ @ @ @ -$ $ @@@@@ -$@$@ :@@$- @ -; *@ @ @ @ @ @ @ @ @ @ $*$: $* @ *@ @ -; @ :@ @ @ @ @ @: -$ @ @ @ $$ @- *@ @ :@ @: :$ -; $+@@: @@@@@ @@@@@@@ @-@$ @@@@@ @@@@@ @@@@@ $* -$$-@@ $+@@: :@@$- -; @ $ -; @@@ @@@@ -; -; - - (define (simplify-ast defns) - (map simplify-defn defns)) - - (define (simplify-defn defn) - (match defn - [(struct ast:defn:iface (_ _ _ _)) - defn] - [(struct ast:defn:class (_ _ _ _ _ _ members _)) - (copy-struct ast:defn:class defn - [ast:defn:class-members (map simplify-member members)])] - [(struct ast:defn:mixin (_ _ _ _ _ _ _ _ super-new members-before members-after _)) - (copy-struct ast:defn:mixin defn - [ast:defn:mixin-super-new (simplify-super-new super-new)] - [ast:defn:mixin-pre-members (map simplify-member members-before)] - [ast:defn:mixin-post-members (map simplify-member members-after)])] - [(struct ast:defn:subclass (_ _ _ _)) - defn] - [(struct ast:defn:function (_ _ _ _ body)) - (copy-struct ast:defn:function defn - [ast:defn:function-body (simplify-expression body)])] - [(struct ast:defn:binding (_ _ _ value)) - (copy-struct ast:defn:binding defn - [ast:defn:binding-init (simplify-expression value)])])) - - (define (simplify-member member) - (match member - [(struct ast:class/member:field/formal (_ _ _ value)) - (if value - (copy-struct ast:class/member:field/formal member - [ast:class/member:field/formal-default (simplify-expression value)]) - member)] - [(struct ast:class/member:field (_ _ _ value)) - (copy-struct ast:class/member:field member - [ast:class/member:field-default (simplify-expression value)])] - [(struct ast:class/member:method (_ _ _ _ body)) - (copy-struct ast:class/member:method member - [ast:class/member:method-body (simplify-expression body)])])) - - (define (simplify-super-new snew) - (match snew - [(struct ast:super-new (_ args)) - (copy-struct ast:super-new snew - [ast:super-new-args (map simplify-name-arg args)])])) - - (define (simplify-name-arg arg) - (match arg - [(struct ast:named/arg (_ _ value)) - (copy-struct ast:named/arg arg - [ast:named/arg-actual (simplify-expression value)])])) - - (define (simplify-expression expr) - (match expr - [(struct ast:expr:self (_)) - expr] - [(struct ast:expr:tuple/select (_ _ arg)) - (copy-struct ast:expr:tuple/select expr - [ast:expr:tuple/select-arg (simplify-expression arg)])] - [(struct ast:expr:var (_ _)) - expr] - [(struct ast:expr:assign (_ lhs rhs)) - (copy-struct ast:expr:assign expr - [ast:expr:assign-lhs (simplify-expression lhs)] - [ast:expr:assign-rhs (simplify-expression rhs)])] - [(struct ast:expr:apply (_ func arg)) - (copy-struct ast:expr:apply expr - [ast:expr:apply-func (simplify-expression func)] - [ast:expr:apply-arg (simplify-expression arg)])] - [(struct ast:expr:literal (_ _ _)) - expr] - [(struct ast:expr:unary/op (_ _ _ _ arg)) - (copy-struct ast:expr:unary/op expr - [ast:expr:unary/op-arg (simplify-expression arg)])] - [(struct ast:expr:binary/op (_ _ _ _ larg rarg)) - (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-left (simplify-expression larg)] - [ast:expr:binary/op-right (simplify-expression rarg)])] - [(struct ast:expr:function (_ _ _ body)) - (copy-struct ast:expr:function expr - [ast:expr:function-body (simplify-expression body)])] - [(struct ast:expr:if (_ cond then else)) - (copy-struct ast:expr:if expr - [ast:expr:if-test (simplify-expression cond)] - [ast:expr:if-then (simplify-expression then)] - [ast:expr:if-else (if else (simplify-expression else) #f)])] - [(struct ast:expr:cast (_ obj _)) - (copy-struct ast:expr:cast expr - [ast:expr:cast-object (simplify-expression obj)])] - [(struct ast:expr:isa (_ obj _)) - (copy-struct ast:expr:isa expr - [ast:expr:isa-object (simplify-expression obj)])] - [(struct ast:expr:member (_ 'my _ _ _)) - expr] - [(struct ast:expr:member (_ obj _ _ _)) - (copy-struct ast:expr:member expr - [ast:expr:member-object (simplify-expression obj)])] - [(struct ast:expr:new (_ _ _ args)) - (copy-struct ast:expr:new expr - [ast:expr:new-args (map simplify-name-arg args)])] - [(struct ast:expr:cond (_ clauses else)) - (copy-struct ast:expr:cond expr - [ast:expr:cond-clauses (map simplify-cond-clause clauses)] - [ast:expr:cond-else (if else (simplify-expression else) #f)])] - [(struct ast:expr:while (_ cond body)) - (copy-struct ast:expr:while expr - [ast:expr:while-test (simplify-expression cond)] - [ast:expr:while-body (simplify-expression body)])] - [(struct ast:expr:return (_ body)) - (copy-struct ast:expr:return expr - [ast:expr:return-result (simplify-expression body)])] - [(struct ast:expr:tuple (_ vals)) - (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems (map simplify-expression vals)])] - [(struct ast:expr:let (stx bindings body)) - (let ([bindings (map simplify-binding bindings)] - [body (simplify-expression body)]) - (match body - [(struct ast:expr:let (_ sub-bindings sub-body)) - (make-ast:expr:let stx (append bindings sub-bindings) sub-body)] - [_ - (copy-struct ast:expr:let expr - [ast:expr:let-bindings bindings] - [ast:expr:let-body body])]))] - [(struct ast:expr:sequence (stx effects value)) - (let ([effects (map simplify-expression effects)] - [value (simplify-expression value)]) - (match value - [(struct ast:expr:sequence (_ sub-effects sub-value)) - (make-ast:expr:sequence stx (append effects sub-effects) sub-value)] - [_ - (copy-struct ast:expr:sequence expr - [ast:expr:sequence-statements effects] - [ast:expr:sequence-result value])]))])) - - (define (simplify-binding binding) - (match binding - [(struct ast:defn:binding (_ _ _ value)) - (copy-struct ast:defn:binding binding - [ast:defn:binding-init (simplify-expression value)])])) - - (define (simplify-cond-clause clause) - (match clause - [(struct ast:cond/clause (_ pred rhs)) - (copy-struct ast:cond/clause clause - [ast:cond/clause-test (simplify-expression pred)] - [ast:cond/clause-result (simplify-expression rhs)])])) - ) diff --git a/collects/honu/private/compiler/translate-class-utils.ss b/collects/honu/private/compiler/translate-class-utils.ss deleted file mode 100644 index c07852579d..0000000000 --- a/collects/honu/private/compiler/translate-class-utils.ss +++ /dev/null @@ -1,184 +0,0 @@ -(module translate-class-utils mzscheme - - (require (lib "list.ss" "srfi" "1") - (only (lib "list.ss") quicksort) - (lib "plt-match.ss") - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../tools/general.ss" - "../typechecker/type-utils.ss" - "translate-expression.ss" - "translate-utils.ss") - - (define-struct comp:export (stx type binds) #f) - (define-struct comp:exp-bind (old new method?) #f) - - (provide translate-class-exports translate-subclass-exports) - (define (translate-class-exports exports) - (let ([exports (filter-exports (generate-exports exports))]) - (map (lambda (e) - (translate-export #f e)) - exports))) - - (define (translate-subclass-exports super-types exports) - (let ([exports (filter-exports (generate-exports exports))]) - (map (lambda (e) - (if (ormap (lambda (t) - (<:_P t (comp:export-type e))) - super-types) - (translate-export #t e) - (translate-export #f e))) - exports))) - - - - (define (generate-super-exports type-entry comp-binds) - (let loop ([super-types (tenv:type-supers type-entry)] - [super-comp-exps '()]) - (if (null? super-types) - super-comp-exps - (let ([super-entry (get-type-entry (car super-types))]) - (let loop2 ([super-members (append (tenv:type-members super-entry) - (tenv:type-inherited super-entry))] - [super-comp-binds '()]) - (if (null? super-members) - (loop (cdr super-types) - (cons (make-comp:export #f (car super-types) super-comp-binds) - (append (generate-super-exports super-entry comp-binds) - super-comp-exps))) - (let ([matched (find (lambda (eb) - (tenv-key=? (tenv:member-name (car super-members)) - (comp:exp-bind-new eb))) - comp-binds)]) - (loop2 (cdr super-members) - (cons matched super-comp-binds))))))))) - - - (define (generate-exports exports) - (let loop ([exports exports] - [comp-exps '()]) - (if (null? exports) - comp-exps - (let* ([export (car exports)] - [type-entry (get-type-entry (ast:export-type export))]) - (let loop2 ([exp-binds (ast:export-members export)] - [members (append (tenv:type-members type-entry) - (tenv:type-inherited type-entry))] - [comp-binds '()]) - (if (null? exp-binds) - (let ([super-exports (generate-super-exports type-entry comp-binds)]) - (loop (cdr exports) - (cons (make-comp:export (ast-syntax export) - (ast:export-type export) - comp-binds) - (append super-exports comp-exps)))) - (let-values ([(matched non-matches) (partition-first (lambda (m) - (tenv-key=? (ast:export/member-external (car exp-binds)) - (tenv:member-name m))) - members)]) - (loop2 (cdr exp-binds) - non-matches - (cons (make-comp:exp-bind (ast:export/member-internal (car exp-binds)) - (ast:export/member-external (car exp-binds)) - (ast:type:method? (tenv:member-type matched))) - comp-binds))))))))) - - (define (sort-binds export) - (quicksort (comp:export-binds export) - (lambda (b1 b2) - (tenv-keysymbol (string-append "init-" (symbol->string (syntax-e name)))))) - - (define (translate-member member) - (match member - [(struct ast:class/member:field/formal (stx name type value)) - (if value - (at stx`(begin (init ([,(mangle-init-name name) ,(at-ctxt name)] - ,(translate-expression value))) - (define ,(at-ctxt name) ,(mangle-init-name name)))) - (at stx `(begin (init ([,(mangle-init-name name) ,(at-ctxt name)])) - (define ,(at-ctxt name) ,(mangle-init-name name)))))] - [(struct ast:class/member:field (stx name type value)) - (at stx `(define ,(at-ctxt name) ,(translate-expression value)))] - [(struct ast:class/member:method (stx name type formals body)) - (translate-function stx name formals (translate-expression body))])) - - - ) diff --git a/collects/honu/private/compiler/translate-expression.ss b/collects/honu/private/compiler/translate-expression.ss deleted file mode 100644 index 26f2e59263..0000000000 --- a/collects/honu/private/compiler/translate-expression.ss +++ /dev/null @@ -1,308 +0,0 @@ -(module translate-expression mzscheme - - (require (lib "contract.ss") - (lib "plt-match.ss") - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../typechecker/type-utils.ss" - "translate-utils.ss") - - (provide/contract [translate-expression (ast:expr? - . -> . - (syntax/c any/c))]) - (define (translate-expression expr) - (match expr - [(struct ast:expr:literal (stx _ value)) - (at stx value)] - [(struct ast:expr:var (stx name)) - (at-ctxt name)] - [(struct ast:expr:tuple (stx args)) - ;; list is a bindable name in Honu, so... we use list*, which isn't. - (at stx `(list* ,@(map translate-expression args) ()))] - [(struct ast:expr:function (stx _ formals body)) - (translate-function stx #f formals (translate-expression body))] - [(struct ast:expr:apply (stx func arg)) - (match func - [(struct ast:expr:member (stx 'my _ name #t)) - (at stx (translate-static-method name (translate-expression arg)))] - [(struct ast:expr:member (stx obj elab name #t)) - (at stx `(honu:send ,(translate-expression obj) - ,(translate-method-name elab name) - ,(translate-expression arg)))] - [else - (at stx `(,(translate-expression func) - ,(translate-expression arg)))])] - [(struct ast:expr:tuple/select (stx slot arg)) - (at stx `(list-ref ,(translate-expression arg) - (- ,slot 1)))] - [(struct ast:expr:if (stx test then else)) - (if else - (at stx `(if ,(translate-expression test) - ,(translate-expression then) - ,(translate-expression else))) - (at stx `(if ,(translate-expression test) - ,(translate-expression then) - ,void-value)))] - [(struct ast:expr:cond (stx clauses else)) - (if else - (at stx `(cond ,@(map (lambda (c) - `(,(translate-expression (ast:cond/clause-test c)) - ,(translate-expression (ast:cond/clause-result c)))) - clauses) - (else ,(translate-expression else)))) - (at stx `(cond ,@(map (lambda (c) - `(,(translate-expression (ast:cond/clause-test c)) - ,(translate-expression (ast:cond/clause-result c)))) - clauses) - (else ,void-value))))] - [(struct ast:expr:unary/op (stx op op-stx op-type arg)) - (case op - [(not) - (at stx - `(,(at op-stx 'not) ,(translate-expression arg)))] - [(minus) - (at stx - `(,(at op-stx '-) ,(translate-expression arg)))] - [else (raise-read-error-with-stx - "Haven't translated unary operator yet." - op-stx)])] - [(struct ast:expr:binary/op (stx op op-stx op-type larg rarg)) - (case op - [(equal) - (if (and (ast:type:primitive? op-type) - (eqv? (ast:type:primitive-name op-type) 'string)) - (at stx - `(,(at op-stx 'string=?) - ,(translate-expression larg) - ,(translate-expression rarg))) - (at stx - `(,(at op-stx 'eqv?) - ,(translate-expression larg) - ,(translate-expression rarg))))] - [(neq) - (if (and (ast:type:primitive? op-type) - (eqv? (ast:type:primitive-name op-type) 'string)) - (at stx - `(,(at op-stx 'not) - (,(at op-stx 'string=?) - ,(translate-expression larg) - ,(translate-expression rarg)))) - (at stx - `(,(at op-stx 'not) - (,(at op-stx 'eqv?) - ,(translate-expression larg) - ,(translate-expression rarg)))))] - [(clseq) - (at stx - `(,(at op-stx 'equal?) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(and) - (at stx - `(,(at op-stx 'and) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(or) - (at stx - `(,(at op-stx 'or) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(lt) - (case (ast:type:primitive-name op-type) - [(int float) - (at stx - `(,(at op-stx '<) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(string) - (at stx - `(,(at op-stx 'string) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(string) - (at stx - `(,(at op-stx 'string>?) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(char) - (at stx - `(,(at op-stx 'char>?) - ,(translate-expression larg) - ,(translate-expression rarg)))])] - [(ge) - (case (ast:type:primitive-name op-type) - [(int float) - (at stx - `(,(at op-stx '>=) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(string) - (at stx - `(,(at op-stx 'string>=?) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(char) - (at stx - `(,(at op-stx 'char>=?) - ,(translate-expression larg) - ,(translate-expression rarg)))])] - [(plus) - (case (ast:type:primitive-name op-type) - [(int float) - (at stx - `(,(at op-stx '+) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(string) - (at stx - `(,(at op-stx 'string-append) - ,(translate-expression larg) - ,(translate-expression rarg)))])] - [(minus) - (at stx - `(,(at op-stx '-) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(times) - (at stx - `(,(at op-stx '*) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(div) - (case (ast:type:primitive-name op-type) - [(int) - (at stx - `(,(at op-stx 'quotient) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [(float) - (at stx - `(,(at op-stx '/) - ,(translate-expression larg) - ,(translate-expression rarg)))])] - [(mod) - (at stx - `(,(at op-stx 'remainder) - ,(translate-expression larg) - ,(translate-expression rarg)))] - [else (raise-read-error-with-stx - "Haven't translated binary operator yet." - op-stx)])] - [(struct ast:expr:return (stx body)) - (at stx - `(last-k ,(translate-expression body)))] - [(struct ast:expr:let (stx bindings body)) - (at stx - `(let*-values ,(map (lambda (b) - (let-values ([(bound-names body) - (translate-binding-clause (ast:defn:binding-names b) - (translate-expression (ast:defn:binding-init b)))]) - ;; make sure to give the let binding the appropriate syntax, - ;; otherwise errors will highlight the entire let expression. - (at (ast-syntax b) `(,bound-names ,body)))) - bindings) - ,(translate-expression body)))] - [(struct ast:expr:sequence (stx effects value)) - (at stx - `(begin ,@(map translate-expression effects) - ,(translate-expression value)))] - [(struct ast:expr:while (stx test body)) - (at stx - `(let loop () - (if ,(translate-expression test) - (begin ,(translate-expression body) (loop)) - ,void-value)))] - [(struct ast:expr:assign (stx lhs rhs)) - (match lhs - [(struct ast:expr:var (_ _)) - (at stx `(begin (set! ,(translate-expression lhs) - ,(translate-expression rhs)) - ,void-value))] - [(struct ast:expr:member (mstx 'my _ name method?)) - (if method? - (raise-read-error-with-stx - "Left-hand side of assignment cannot be a method name" - mstx) - (at stx (translate-static-field-setter name (translate-expression rhs))))] - [(struct ast:expr:member (mstx obj elab name method?)) - (if method? - (raise-read-error-with-stx - "Left-hand side of assignment cannot be a method name" - mstx) - (at stx `(honu:send ,(translate-expression obj) - ,(translate-field-setter-name elab name) - ,(translate-expression rhs))))] - [else - (raise-read-error-with-stx - "Left-hand side of assignment is invalid" - stx)])] - [(struct ast:expr:member (stx 'my _ name method?)) - (if method? - (at stx (translate-static-method name)) - (at stx (translate-static-field-getter name)))] - [(struct ast:expr:member (stx obj elab name method?)) - (if method? - (at stx `(lambda (args) - (honu:send ,(translate-expression obj) - ,(translate-method-name elab name) - args))) - (at stx `(honu:send ,(translate-expression obj) - ,(translate-field-getter-name elab name) - ,void-value)))] - [(struct ast:expr:new (stx class _ args)) - (at stx `(new ,(translate-class-name class) - ,@(map (lambda (a) - `(,(ast:named/arg-name a) - ,(translate-expression (ast:named/arg-actual a)))) - args)))] - [(struct ast:expr:cast (stx obj type)) - (at stx `(let ([cast-obj ,(translate-expression obj)]) - ;; you can always cast null to an interface type - (if (or (is-a? cast-obj null%) - (honu:send cast-obj implements? ,(translate-iface-name type))) - cast-obj - (error (format "Class ~a does not implement ~a" - (honu:send cast-obj format-class-name) - (quote ,(syntax-e (iface-name type))))))))] - [(struct ast:expr:isa (stx obj type)) - (at stx `(let ([cast-obj ,(translate-expression obj)]) - ;; null is a member of any interface type - (or (is-a? cast-obj null%) - (honu:send cast-obj implements? ,(translate-iface-name type)))))] - [(struct ast:expr:self (stx)) - (at stx 'this)] - [else (raise-read-error-with-stx - "Haven't translated that type of expression yet." - (ast-syntax expr))])) - - ) diff --git a/collects/honu/private/compiler/translate-parameters.ss b/collects/honu/private/compiler/translate-parameters.ss deleted file mode 100644 index 72c69404ad..0000000000 --- a/collects/honu/private/compiler/translate-parameters.ss +++ /dev/null @@ -1,7 +0,0 @@ -(module translate-parameters mzscheme - - (provide (all-defined)) - - (define current-mixin-argument-type (make-parameter #f)) - - ) \ No newline at end of file diff --git a/collects/honu/private/compiler/translate-unwanted-types.ss b/collects/honu/private/compiler/translate-unwanted-types.ss deleted file mode 100644 index 63eabd18eb..0000000000 --- a/collects/honu/private/compiler/translate-unwanted-types.ss +++ /dev/null @@ -1,168 +0,0 @@ -(module translate-unwanted-types mzscheme - - (require (lib "list.ss" "srfi" "1") - (lib "plt-match.ss") - "../../ast.ss" - "translate-utils.ss") - - (provide build-unwanted-type-syntax) - (define (build-unwanted-type-syntax defns) - (map build-unwanted-type-syntax-defn defns)) - - ;; since we're never going to run the result anyway, it doesn't matter - ;; how we build things -- no need to flatten. - (define (build-unwanted-type-syntax-defn defn) - (match defn - [(struct ast:defn:binding (_ _ types value)) - (cons (build-unwanted-type-syntax-expression value) - ;; remember to filter out the top types used whenever _ appears - (map translate-type-for-syntax (filter (lambda (t) (not (ast:type:top? t))) types)))] - [(struct ast:defn:function (_ _ type formals body)) - (list (translate-type-for-syntax type) - (build-unwanted-type-syntax-expression body) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - formals))] - [(struct ast:defn:iface (_ _ _ members)) - (map build-unwanted-type-syntax-member-decl members)] - [(struct ast:defn:class (_ _ selftype _ _ inits members exports)) - (list (translate-type-for-syntax selftype) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - inits) - (map build-unwanted-type-syntax-member members) - (map (lambda (e) - (translate-type-for-syntax (ast:export-type e))) - exports))] - [(struct ast:defn:mixin (_ _ selftype arg-type _ _ inits withs super-new - members-before members-after exports)) - (list (translate-type-for-syntax selftype) - (translate-type-for-syntax arg-type) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - inits) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - withs) - (map (lambda (a) - (build-unwanted-type-syntax-expression (ast:named/arg-actual a))) - (ast:super-new-args super-new)) - (map build-unwanted-type-syntax-member members-before) - (map build-unwanted-type-syntax-member members-after) - (map (lambda (e) - (translate-type-for-syntax (ast:export-type e))) - exports))] - [(struct ast:defn:subclass (_ _ _ mixin)) - ;; okay, this isn't a type, but we still want to see it as a use - ;; until we can translate mixins correctly. - (list (translate-mixin-name mixin))])) - - (define (build-unwanted-type-syntax-member-decl member) - (match member - [(struct ast:iface/member:field (_ _ type)) - (translate-type-for-syntax type)] - [(struct ast:iface/member:method (_ _ type arg-types)) - (list (translate-type-for-syntax type) - (map translate-type-for-syntax arg-types))])) - - (define (build-unwanted-type-syntax-member member) - (match member - [(struct ast:class/member:field/formal (_ _ type value)) - (list (translate-type-for-syntax type) - (if value (build-unwanted-type-syntax-expression value) '()))] - [(struct ast:class/member:field (_ _ type value)) - (list (translate-type-for-syntax type) - (build-unwanted-type-syntax-expression value))] - [(struct ast:class/member:method (_ _ type formals body)) - (list (translate-type-for-syntax type) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - formals) - (build-unwanted-type-syntax-expression body))])) - - (define (build-unwanted-type-syntax-expression expr) - (match expr - [(struct ast:expr:function (_ type formals body)) - (list (translate-type-for-syntax type) - (map (lambda (f) - (translate-type-for-syntax (ast:formal-type f))) - formals) - (build-unwanted-type-syntax-expression body))] - [(struct ast:expr:let (_ bindings body)) - (list (map (lambda (b) - ;; again, make sure to remove types corresponding to _ - (list (map translate-type-for-syntax (filter (lambda (t) - (not (ast:type:top? t))) - (ast:defn:binding-types b))) - (build-unwanted-type-syntax-expression (ast:defn:binding-init b)))) - bindings) - (build-unwanted-type-syntax-expression body))] - [(struct ast:expr:sequence (_ effects result)) - (list (map (lambda (e) - (build-unwanted-type-syntax-expression e)) - effects) - (build-unwanted-type-syntax-expression result))] - [(struct ast:expr:apply (_ func arg)) - (list (build-unwanted-type-syntax-expression func) - (build-unwanted-type-syntax-expression arg))] - [(struct ast:expr:assign (_ lhs rhs)) - (list (build-unwanted-type-syntax-expression lhs) - (build-unwanted-type-syntax-expression rhs))] - [(struct ast:expr:return (_ body)) - (build-unwanted-type-syntax-expression body)] - [(struct ast:expr:tuple/select (_ _ arg)) - (build-unwanted-type-syntax-expression arg)] - [(struct ast:expr:tuple (_ args)) - (map build-unwanted-type-syntax-expression args)] - [(struct ast:expr:member (_ obj _ _ _)) - (if (ast:expr? obj) - (build-unwanted-type-syntax-expression obj) - (list))] - [(struct ast:expr:new (_ obj type args)) - (list (build-unwanted-type-syntax-expression obj) - (translate-type-for-syntax type) - (map (lambda (a) - (build-unwanted-type-syntax-expression (ast:named/arg-actual a))) - args))] - ;; here are the two cases where the type already appears in the compiled code - [(struct ast:expr:cast (_ obj _)) - (build-unwanted-type-syntax-expression obj)] - [(struct ast:expr:isa (_ obj _)) - (build-unwanted-type-syntax-expression obj)] - [(struct ast:expr:unary/op (_ _ _ _ arg)) - (build-unwanted-type-syntax-expression arg)] - [(struct ast:expr:binary/op (_ _ _ _ larg rarg)) - (list (build-unwanted-type-syntax-expression larg) - (build-unwanted-type-syntax-expression rarg))] - [(struct ast:expr:if (_ cond then else)) - (list (build-unwanted-type-syntax-expression cond) - (build-unwanted-type-syntax-expression then) - (build-unwanted-type-syntax-expression else))] - [(struct ast:expr:cond (_ clauses else)) - (list (map (lambda (c) - (list (build-unwanted-type-syntax-expression (ast:cond/clause-test c)) - (build-unwanted-type-syntax-expression (ast:cond/clause-result c)))) - clauses) - (if else (build-unwanted-type-syntax-expression else) '()))] - [else '()])) - - ;; Yes, this is just part of the hack that gives us Check Syntax-correctness on all the types that - ;; are not otherwise used in the compiled code. - (provide translate-type-for-syntax) - (define (translate-type-for-syntax type) - (define (real-translation type) - (match type - [(struct ast:type:object:iface (stx name)) - (translate-iface-name type)] - [(struct ast:type:object:any (stx)) - (translate-iface-name type)] - [(struct ast:type:primitive (stx name)) - '()] - [(struct ast:type:function (stx arg ret)) - (list (real-translation arg) - (real-translation ret))] - [(struct ast:type:tuple (stx args)) - (map real-translation args)])) - (real-translation type)) - - ) \ No newline at end of file diff --git a/collects/honu/private/compiler/translate-utils.ss b/collects/honu/private/compiler/translate-utils.ss deleted file mode 100644 index b8c77c84b4..0000000000 --- a/collects/honu/private/compiler/translate-utils.ss +++ /dev/null @@ -1,139 +0,0 @@ -(module translate-utils mzscheme - - (require (all-except (lib "list.ss" "srfi" "1") any) - (lib "contract.ss") - "../../ast.ss" - "../../parameters.ss" - "../../tenv.ss" - "translate-parameters.ss") - - (define stx-for-original-property (read-syntax #f (open-input-string "original"))) - - (provide/contract [at ((union (syntax/c any/c) false/c) - any/c - . -> . - (syntax/c any/c))] - [at-ctxt ((syntax/c any/c) . -> . (syntax/c any/c))]) - (define (at stx expr) - (datum->syntax-object (current-compile-context) expr stx stx-for-original-property)) - (define (at-ctxt stx) - (datum->syntax-object (current-compile-context) (syntax-e stx) stx stx-for-original-property)) - - (provide void-value) - (define void-value '()) - - (provide translate-function) - (define (translate-function stx name args body) - (define (wrapping-syntax arg body) - (if name - (at stx `(define (,(at-ctxt name) ,arg) - (let/ec last-k ,body))) - (at stx `(lambda (,arg) - (let/ec last-k ,body))))) - (if (= (length args) 1) - (wrapping-syntax (at-ctxt (ast:formal-name (car args))) - body) - (wrapping-syntax (at #f 'arg-tuple) - `(let-values ([,(map (lambda (a) - (at-ctxt (ast:formal-name a))) - args) - (apply values ,(at #f 'arg-tuple))]) - ,body)))) - - (provide translate-binding-clause) - (define (translate-binding-clause names value) - (define (grab-indices names) - (let loop ([names names] - [n 0] - [ret '()]) - (cond - [(null? names) - (reverse ret)] - [(car names) - (loop (cdr names) - (+ n 1) - (cons `(list-ref arg-tuple ,n) ret))] - [else - (loop (cdr names) - (+ n 1) - ret)]))) - (values (filter (lambda (n) n) names) - `(let ([arg-tuple ,(if (= (length names) 1) - `(list* ,value ()) - value)]) - ,(cons 'values (grab-indices names))))) - - (provide translate-iface-name translate-class-name translate-mixin-name translate-method-name - translate-field-getter-name translate-field-setter-name) - (define (translate-iface-name type) - (let ([name (if (ast:type:object:any? type) - (datum->syntax-object #f 'Any (ast-syntax type)) - (ast:type:object:iface-name type))]) - (at name (string->symbol (string-append (symbol->string (syntax-e name)) "<%>"))))) - - (define (translate-class-name class) - (at class (string->symbol (string-append (symbol->string (syntax-e class)) "%")))) - (define (translate-mixin-name mixin) - (at mixin (string->symbol (string-append (symbol->string (syntax-e mixin)) "-mixin")))) - - (define (translate-method-name type name) - (at name (string->symbol (string-append (symbol->string (syntax-e (translate-iface-name type))) - "-" - (symbol->string (syntax-e name)))))) - - (define (translate-field-getter-name type name) - (at name (string->symbol (string-append (symbol->string (syntax-e (translate-iface-name type))) - "-" - (symbol->string (syntax-e name)) - "-get")))) - - (define (translate-field-setter-name type name) - (at name (string->symbol (string-append (symbol->string (syntax-e (translate-iface-name type))) - "-" - (symbol->string (syntax-e name)) - "-set!")))) - - (provide translate-static-method translate-static-field-getter translate-static-field-setter) - (define (translate-static-method name arg) - (if (current-mixin-argument-type) - (let ([type-entry (get-type-entry (current-mixin-argument-type))]) - (if (s:member name - (map tenv:member-name (append (tenv:type-members type-entry) - (tenv:type-inherited type-entry))) - tenv-key=?) - (if arg - `(super ,(translate-method-name (current-mixin-argument-type) name) ,arg) - `(lambda (arg-tuple) - (super ,(translate-method-name (current-mixin-argument-type) name) arg-tuple))) - (if arg - `(,(at-ctxt name) ,arg) - (at-ctxt name)))) - (if arg - `(,(at-ctxt name) ,arg) - (at-ctxt name)))) - - (define (translate-static-field-getter name) - (if (current-mixin-argument-type) - (let ([type-entry (get-type-entry (current-mixin-argument-type))]) - (if (s:member name - (map tenv:member-name (append (tenv:type-members type-entry) - (tenv:type-inherited type-entry))) - tenv-key=?) - `(super ,(translate-field-getter-name (current-mixin-argument-type) name) ,void-value) - (at-ctxt name))) - (at-ctxt name))) - - (define (translate-static-field-setter name arg) - (if (current-mixin-argument-type) - (let ([type-entry (get-type-entry (current-mixin-argument-type))]) - (if (s:member name - (map tenv:member-name (append (tenv:type-members type-entry) - (tenv:type-inherited type-entry))) - tenv-key=?) - `(super ,(translate-field-setter-name (current-mixin-argument-type) name) ,arg) - `(begin (set! ,(at-ctxt name) ,arg) - ,void-value))) - `(begin (set! ,(at-ctxt name) ,arg) - ,void-value))) - - ) diff --git a/collects/honu/private/compiler/translate.ss b/collects/honu/private/compiler/translate.ss deleted file mode 100644 index d1f568335d..0000000000 --- a/collects/honu/private/compiler/translate.ss +++ /dev/null @@ -1,159 +0,0 @@ -(module translate mzscheme - - (require (all-except (lib "list.ss" "srfi" "1") any) - (lib "contract.ss") - (lib "plt-match.ss") - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../typechecker/type-utils.ss" - "translate-class-utils.ss" - "translate-expression.ss" - "translate-parameters.ss" - "translate-unwanted-types.ss" - "translate-utils.ss") - - (provide/contract [translate (((listof ast:defn?)) - . ->* . - (any/c (listof (syntax/c any/c))))] - [translate-defn (ast:defn? - . -> . - (syntax/c any/c))]) - (define (translate defns) - (let loop ([defns-to-go defns] - [syntaxes '()]) - (cond - [(null? defns-to-go) - (values (build-unwanted-type-syntax defns) - ( reverse syntaxes))] - [(ast:defn:subclass? (car defns-to-go)) - (let ([mixin (find (lambda (d) - (and (ast:defn:mixin? d) - (tenv-key=? (ast:defn:mixin-name d) - (ast:defn:subclass-mixin (car defns-to-go))))) - defns)]) - (loop (cdr defns-to-go) (cons (translate-subclass mixin (car defns-to-go)) syntaxes)))] - [else - (loop (cdr defns-to-go) (cons (translate-defn (car defns-to-go)) syntaxes))]))) - - (define (translate-iface-member-names name) - (let* ([iface (make-iface-type name name)] - [type-entry (get-type-entry iface)]) - (let loop ([members (append (tenv:type-members type-entry) (tenv:type-inherited type-entry))] - [names '()]) - (if (null? members) - (reverse names) - (if (ast:type:method? (tenv:member-type (car members))) - (loop (cdr members) - (cons (translate-method-name iface (tenv:member-name (car members))) - names)) - (loop (cdr members) - (cons (translate-field-setter-name iface (tenv:member-name (car members))) - (cons (translate-field-getter-name iface (tenv:member-name (car members))) - names)))))))) - - (define (translate-defn defn) - (match defn - [(struct ast:defn:binding (stx names types value)) - (let-values ([(bound-names body) (translate-binding-clause names (translate-expression value))]) - (at stx `(define-values ,bound-names ,body)))] - [(struct ast:defn:function (stx name type args body)) - (translate-function stx name args (translate-expression body))] - [(struct ast:defn:iface (stx name supers members)) - (at stx `(define ,(translate-iface-name (make-iface-type name name)) - (interface ,(if (null? supers) - (list (translate-iface-name (make-any-type #f))) - (map translate-iface-name supers)) - ,@(translate-iface-member-names name))))] - [(struct ast:defn:class (stx name selftype _ impls inits members exports)) - (at stx `(define ,(translate-class-name name) - (class* object% ,(map translate-iface-name impls) - (inspect #f) - ,(translate-inits inits) - ,@(map translate-member members) - ,@(translate-class-exports exports) - ,(translate-impl-method impls) - ,(translate-formatter name members) - (super-new))))] - [(struct ast:defn:mixin (stx name _ _ _ _ _ _ _ _ _ _)) - ;; just a dummy definition to get the bindings set up correctly - (at stx `(define ,(translate-mixin-name name) - '()))] - [else (raise-read-error-with-stx - "Haven't translated that type of definition yet." - (ast-syntax defn))])) - - (define (translate-subclass mixin-defn defn) - (match (list mixin-defn defn) - [(list (struct ast:defn:mixin (mstx mname selftype arg-type _ impls inits withs super-new members-before members-after exports)) - (struct ast:defn:subclass (stx name base mixin))) - (parameterize ([current-mixin-argument-type arg-type]) - (let* ([base-entry (get-class-entry base)] - [base-types (cons (tenv:class-sub-type base-entry) - (tenv:class-impls base-entry))]) - (at stx `(define ,(translate-class-name name) - (class* ,(translate-class-name base) ,(map translate-iface-name impls) - (inspect #f) - ,(translate-inits inits) - ,@(map translate-member members-before) - ,(translate-super-new super-new) - ,@(map translate-member members-after) - ,@(translate-subclass-exports base-types exports) - ,(translate-impl-method impls) - ,(translate-formatter name (append members-before members-after)))))))])) - - (define (translate-impl-method impls) - (let ([right-define (if (current-mixin-argument-type) 'define/override 'define/public)]) - `(,right-define (implements? iface) - (mz:ormap (lambda (i) - (interface-extension? i iface)) - (list* ,@(map translate-iface-name impls) '()))))) - - (define (translate-formatter name members) - (let ([right-define (if (current-mixin-argument-type) 'define/override 'define/public)]) - `(begin - (,right-define (format-class-name) - ,(format "~a" (syntax-e name))) - (,right-define (format-class renderer indent) - (format "~a {~a}" - (format-class-name) - ,(cons 'string-append - (let ([printable-members (filter (lambda (m) - (not (ast:class/member:method? m))) - members)] - [printable-smembers (if (current-mixin-argument-type) - (filter-map (lambda (m) - (if (not (ast:type:method? (tenv:member-type m))) - (tenv:member-name m) - #f)) - (tenv:type-members (get-type-entry (current-mixin-argument-type)))) - '())] - ;; how much more do we want the members indented? Let's try 2 spaces more. - [indent-delta 2]) - (if (and (null? printable-members) - (null? printable-smembers)) - '("") - (fold-right (lambda (m l) - (list* "\n" (translate-super-member-formatter m indent-delta) l)) - (fold-right (lambda (m l) - (list* "\n" (translate-member-formatter m indent-delta) l)) - '("\n" (make-string indent #\space)) - printable-members) - printable-smembers))))))))) - - (define (translate-member-formatter member indent-delta) - (let ([name (ast:class/member-name member)]) - `(format "~a~a = ~a;" - (make-string (+ indent ,indent-delta) #\space) - (quote ,(syntax-e name)) - ;; the 3 is for " = " - (renderer ,name (+ indent ,(+ indent-delta (string-length (symbol->string (syntax-e name))) 3)))))) - - (define (translate-super-member-formatter name indent-delta) - `(format "~a~a = ~a;" - (make-string (+ indent ,indent-delta) #\space) - (quote ,(syntax-e name)) - ;; as before, the 3 is for " = " - (renderer ,(translate-static-field-getter name) - (+ indent ,(+ indent-delta (string-length (symbol->string (syntax-e name))) 3))))) - ) diff --git a/collects/honu/private/tests/program-tests.ss b/collects/honu/private/tests/program-tests.ss deleted file mode 100644 index bac52098f5..0000000000 --- a/collects/honu/private/tests/program-tests.ss +++ /dev/null @@ -1,48 +0,0 @@ -(module program-tests mzscheme - - (require (lib "contract.ss") - (planet "test.ss" ("schematics" "schemeunit.plt" 1 1)) - (prefix srfi1: (lib "1.ss" "srfi")) - "../../top.ss" - ) - - (provide/contract [program-tests test-suite?]) - - (define program-files - (list "examples/BoundedStack.honu" - "examples/EvenOddClass.honu" - "examples/List.honu" - "examples/Y.honu" - "examples/bind-tup-top.honu" - "examples/cond-test.honu" - "examples/even-odd.honu" - "examples/exprs.honu" - "examples/point.honu" - "examples/struct.honu" - "examples/tup-bind.honu" -; "examples/types-error.honu" - "examples/types.honu" -; "examples/nonexistent.honu" - )) - - (define-assertion (assert-test-file program-file) - (let* ([results (test-file program-file)] - [indices (srfi1:iota (length results))] - [errors - (srfi1:filter-map (lambda (result index) (if result #f index)) - results indices)]) - (if (null? errors) - #t - (with-assertion-info - (['error-indices errors]) - (fail-assertion))))) - - (define (make-program-test program-file) - (make-test-case program-file (assert-test-file program-file))) - - (define program-tests - (apply make-test-suite - "Honu" - (map make-program-test program-files))) - - ) diff --git a/collects/honu/private/tests/typechecker-tests.ss b/collects/honu/private/tests/typechecker-tests.ss deleted file mode 100644 index 8852009546..0000000000 --- a/collects/honu/private/tests/typechecker-tests.ss +++ /dev/null @@ -1,38 +0,0 @@ -(module typechecker-tests mzscheme - - (require (lib "contract.ss") - (planet "test.ss" ("schematics" "schemeunit.plt" 1 1)) - (prefix srfi13: (lib "13.ss" "srfi")) - "../typechecker/typecheck-expression.ss" - "../../tenv.ss" - "../../ast.ss" - ) - - (provide/contract [typechecker-tests test-suite?]) - - (define non-void-in-sequence-test - (make-test-case "Non-void expression in a sequence" - (assert-exn - (lambda (exn) - (srfi13:string-contains (exn-message exn) "void")) - (lambda () - (typecheck-expression - (wrap-lenv) #f - (make-ast:expr:sequence - #'() - (list (make-ast:expr:literal #'() (make-ast:type:primitive #'() 'int) #'5)) - (make-ast:expr:literal #'() (make-ast:type:primitive #'() 'int) #'4))))))) - - (define error-message-tests - (make-test-suite - "Error messages" - non-void-in-sequence-test - )) - - (define typechecker-tests - (make-test-suite - "Typechecker" - error-message-tests - )) - - ) \ No newline at end of file diff --git a/collects/honu/private/tools/general.ss b/collects/honu/private/tools/general.ss deleted file mode 100644 index e179d34b43..0000000000 --- a/collects/honu/private/tools/general.ss +++ /dev/null @@ -1,100 +0,0 @@ -(module general mzscheme - - (require (prefix srfi1: (lib "list.ss" "srfi" "1")) - (lib "list.ss")) - - (provide fold-with-rest - get-first-non-unique-name - map-and-fold - map-two-values - map-values - partition-first - unique? - curry - false?) - - (define (map-values-rev-accs f lists accs) - (cond [(andmap empty? lists) (apply values (map reverse accs))] - [(ormap empty? lists) (error 'map-values "expects lists of equal length")] - [else (call-with-values (lambda () (apply f (map first lists))) - (lambda vs (map-values-rev-accs f (map rest lists) (map cons vs accs))))])) - - (define (map-values f . lists) - (cond [(empty? lists) (error 'map-values "expects 1 or more input lists")] - [(ormap empty? lists) (error 'map-values "expects non-empty lists")] - [else - (call-with-values (lambda () (apply f (map first lists))) - (lambda vs (map-values-rev-accs f (map rest lists) (map list vs))))])) - - (define (identifierstring (syntax-e a)) - (symbol->string (syntax-e b)))) - - (define (get-first-non-unique-name lst) - (let loop ([lst (quicksort lst identifierstring name)] - [(struct ast:type:tuple (_ args)) - (if (null? args) - "void" - (string-append "<" - (srfi1:fold (lambda (t i) - (string-append i ", " (printable-type t))) - (printable-type (car args)) - (cdr args)) - ">"))] - [(struct ast:type:partial/tuple (_ slot type)) - (format "tuple of size >= ~a where the type in slot ~a is ~a" - slot slot (printable-type type))] - [(struct ast:type:function (_ arg ret)) - (if (ast:type:function? arg) - (string-append "<" (printable-type arg) "> -> " (printable-type ret)) - (string-append (printable-type arg) " -> " (printable-type ret)))] - [(struct ast:type:method (_ disp arg ret)) - (string-append "[" (printable-type disp) "] " - (printable-type arg) " -> " (printable-type ret))] - [(struct ast:type:object:iface (_ name)) - (symbol->string (syntax-e name))] - [(struct ast:type:object:any (_)) - "Any"] - [(struct ast:type:object:null (_)) - "null"])) - - (provide type-valid?) - (define (type-valid? t) - (match t - [(struct ast:type:object:any (_)) #t] - [(struct ast:type:primitive (stx name)) - (case name - [(int float char string bool) #t] - [else (raise-read-error-with-stx - (format "Unexpected primitive type ~a" name) - stx)])] - [(struct ast:type:object:iface (stx name)) - (let ([tentry (get-tenv-entry name)]) - (and tentry (tenv:type? tentry)))] - [(struct ast:type:tuple (_ args)) - (andmap (lambda (t) - (type-valid? t)) - args)] - [(struct ast:type:function (_ arg ret)) - (and (type-valid? arg) - (type-valid? ret))] - [(struct ast:type:method (_ disp arg ret)) - (and (type-valid? disp) - (type-valid? arg) - (type-valid? ret))])) - - (provide type-equal?) - (define (type-equal? t1 t2) - (cond - ;; first all the easy ones - [(and (ast:type:top? t1) - (ast:type:top? t2)) - #t] - [(and (ast:type:bot? t1) - (ast:type:bot? t2)) - #t] - [(and (ast:type:object:any? t1) - (ast:type:object:any? t2)) - #t] - [(and (ast:type:object:null? t1) - (ast:type:object:null? t2)) - #t] - ;; primitive types are equal if their names are equal. - [(and (ast:type:primitive? t1) - (ast:type:primitive? t2)) - (eqv? (ast:type:primitive-name t1) - (ast:type:primitive-name t2))] - ;; same for ifaces - [(and (ast:type:object:iface? t1) - (ast:type:object:iface? t2)) - (tenv-key=? (ast:type:object:iface-name t1) - (ast:type:object:iface-name t2))] - ;; function, dispatch types are equal if their component types are. - [(and (ast:type:function? t1) - (ast:type:function? t2)) - (and (type-equal? (ast:type:function-input t1) (ast:type:function-input t2)) - (type-equal? (ast:type:function-output t1) (ast:type:function-output t2)))] - [(and (ast:type:method? t1) - (ast:type:method? t2)) - (and (type-equal? (ast:type:method-receiver t1) (ast:type:method-receiver t2)) - (type-equal? (ast:type:method-input t1) (ast:type:method-input t2)) - (type-equal? (ast:type:method-output t1) (ast:type:method-output t2)))] - ;; tuple types are equal if they have the same number of components and - ;; their components are pairwise equal - [(and (ast:type:tuple? t1) - (ast:type:tuple? t2)) - (let ([t1-args (ast:type:tuple-elems t1)] - [t2-args (ast:type:tuple-elems t2)]) - (and (= (length t1-args) (length t2-args)) - (andmap (lambda (t1 t2) - (type-equal? t1 t2)) - t1-args t2-args)))] - ;; for select types, they must be the same type on the same slot - ;; (should we even get here?) - [(and (ast:type:partial/tuple? t1) - (ast:type:partial/tuple? t2)) - (and (= (ast:type:partial/tuple-position t1) (ast:type:partial/tuple-position t2)) - (type-equal? (ast:type:partial/tuple-elem t1) (ast:type:partial/tuple-elem t2)))] - [else #f])) - - ;; assumes either Any or some type identifier - (define (get-type-name t) - (cond - [(ast:type:object:iface? t) - (ast:type:object:iface-name t)] - [(ast:type:object:any? t) - #'Any])) - - ;; is t1 a _direct_ subtype of t2? - (define (Subtype_P t1 t2) - (let ([type-entry (get-type-entry t1)]) - (match type-entry - [(struct tenv:type (_ supers _ _)) - (let ([super-names (map get-type-name supers)]) - (srfi1:s:member (get-type-name t2) super-names tenv-key=?))]))) - - ;; is t1 a (ref-trans-closed) subtype of t2? - (provide <:_P) - (define (<:_P t1 t2) - (cond - ;; if t1 = t2, t1 <:_P t2 - [(type-equal? t1 t2) - #t] - ;; if t1 is the bottom of the type lattice, then it trivially holds - [(ast:type:bot? t1) - #t] - ;; if t2 is the top of the type lattice, then it trivially holds - [(ast:type:top? t2) - #t] - ;; if t1 =/= t2 and they're both primitives, then they cannot be equal. - [(and (ast:type:primitive? t1) - (ast:type:primitive? t2)) - #f] - ;; for function types... - [(and (ast:type:function? t1) - (ast:type:function? t2)) - ;; the arg is contravariant and the ret is covariant - (and (<:_P (ast:type:function-input t2) (ast:type:function-input t1)) - (<:_P (ast:type:function-output t1) (ast:type:function-output t2)))] - ;; for dispatch types... - [(and (ast:type:method? t1) - (ast:type:method? t2)) - ;; dispatch args must be co-, regular args contra-, and ret co- - (and (<:_P (ast:type:method-receiver t1) (ast:type:method-receiver t2)) - (<:_P (ast:type:method-input t2) (ast:type:method-input t1)) - (<:_P (ast:type:method-output t1) (ast:type:method-output t2)))] - ;; for tuple types... - [(and (ast:type:tuple? t1) - (ast:type:tuple? t2)) - (let ([t1-args (ast:type:tuple-elems t1)] - [t2-args (ast:type:tuple-elems t2)]) - ;; the lengths must be equal... - (and (= (length t1-args) (length t2-args)) - ;; and each component must be a subtype (covariantly) - (andmap (lambda (t1 t2) - (<:_P t1 t2)) - t1-args t2-args)))] - ;; for a select statement (s, t), we have that a tuple type (t_1 ... t_n) is <:_P t if - ;; if t_s <:_P t. - [(and (ast:type:tuple? t1) - (ast:type:partial/tuple? t2)) - (let ([t2-slot (ast:type:partial/tuple-position t2)] - [t1-args (ast:type:tuple-elems t1)]) - (and (<= t2-slot (length t1-args)) - ;; we have to subtract one from t2-slot because list-ref is zero-based - (<:_P (list-ref t1-args (- t2-slot 1)) (ast:type:partial/tuple-elem t2))))] - ;; not sure if this is necessary. Hmm. - [(and (ast:type:partial/tuple? t1) - (ast:type:partial/tuple? t2)) - (and (= (ast:type:partial/tuple-position t1) (ast:type:partial/tuple-position t2)) - (<:_P (ast:type:partial/tuple-elem t1) (ast:type:partial/tuple-elem t2)))] - ;; the bottom of the iface lattice is <:_P either the iface-top or - ;; any iface - [(and (ast:type:object:null? t1) - (or (ast:type:object:iface? t2) - (ast:type:object:any? t2))) - #t] - ;; any iface type is <:_P the iface-top (iface-bot already caught above) - [(and (ast:type:object:iface? t1) - (ast:type:object:any? t2)) - #t] - ;; if two (non-equal) iface types... - [(and (ast:type:object:iface? t1) - (ast:type:object:iface? t2)) - (if (Subtype_P t1 t2) - ;; return true if it's a direct subtype relation - #t - (let ([type-entry (get-type-entry t1)]) - ;; if any of the direct supertypes of t1 is a subtype of t2, - ;; then t1 is also - (ormap (lambda (t) - (<:_P t t2)) - (tenv:type-supers type-entry))))] - [else #f])) - - (provide/contract [type-member-names (ast:type? . -> . (listof identifier?))]) - (define (type-member-names type) - (let* ([entry (get-type-entry type)]) - (map tenv:member-name - (append (tenv:type-members entry) - (tenv:type-inherited entry))))) - - (provide iface-name) - (define (iface-name type) - (match type - [(struct ast:type:object:any (_)) #'Any] - [(struct ast:type:object:iface (_ name)) name])) - - (provide raise-honu-type-error) - (define (raise-honu-type-error stx expected received) - (raise-read-error-with-stx - (format "Expected type ~a, got type ~a" - (printable-type expected) - (printable-type received)) - stx)) - ) diff --git a/collects/honu/private/typechecker/typecheck-class-utils.ss b/collects/honu/private/typechecker/typecheck-class-utils.ss deleted file mode 100644 index e9ad8927b3..0000000000 --- a/collects/honu/private/typechecker/typecheck-class-utils.ss +++ /dev/null @@ -1,273 +0,0 @@ -(module typecheck-class-utils mzscheme - - (require (lib "list.ss" "srfi" "1") - (lib "plt-match.ss") - (lib "struct.ss") - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../tools/general.ss" - "typecheck-expression.ss" - "typecheck-parameters.ss" - "type-utils.ss") - - (provide extend-lenv-with-type-members typecheck-members typecheck-supernew typecheck-exports) - - (define (typecheck-exports lenv selftype init-impls exports) - (let loop ([impls init-impls] - [exports exports]) - (cond - [(and (null? exports) - (null? impls)) - (if (not (s:member selftype init-impls (lambda (t1 t2) (type-equal? t1 t2)))) - (raise-read-error-with-stx - (format "No export statement for self type ~a" - (printable-type selftype)) - (ast-syntax selftype)) - ;; the selftype was already covered by one of the implemented types, so - ;; we can just stop. - (void))] - [(null? exports) - (raise-read-error-with-stx - (format "No export statement for implemented type ~a" - (printable-type (car impls))) - (ast-syntax (car impls)))] - [(null? impls) - (if (s:member selftype init-impls (lambda (t1 t2) (type-equal? t1 t2))) - (raise-read-error-with-stx - (format "Extra export statement for unimplemented type ~a" - (printable-type (ast:export-type (car exports)))) - (ast-syntax (car exports))) - (let-values ([(matched non-matches) (partition-first (lambda (e) - (type-equal? (ast:export-type e) selftype)) - exports)]) - (if (not matched) - (raise-read-error-with-stx - (format "No export statement for self type ~a" - (printable-type selftype)) - (ast-syntax selftype)) - (let ([type-entry (get-type-entry selftype)]) - (typecheck-export lenv type-entry matched) - (if (not (null? non-matches)) - (raise-read-error-with-stx - (format "Extra export statement for unimplemented type ~a" - (printable-type (ast:export-type (car exports)))) - (ast-syntax (car exports))) - (void))))))] - [else - (let-values ([(matched non-matches) (partition-first (lambda (t) - (type-equal? (ast:export-type (car exports)) t)) - impls)]) - (if (not matched) - (raise-read-error-with-stx - (format "Extra export statement for unimplemented type ~a" - (ast:export-type (car exports))) - (ast-syntax (car exports))) - (let* ([type-entry (get-type-entry matched)] - [export (car exports)]) - (typecheck-export lenv type-entry export) - (loop non-matches (cdr exports)))))]))) - - (define (typecheck-export lenv type-entry export) - ;; make sure to use both defined members and inherited members here - (let loop ([type-members (append (tenv:type-members type-entry) (tenv:type-inherited type-entry))] - [export-binds (ast:export-members export)]) - (cond - [(and (null? type-members) - (null? export-binds)) - (void)] - [(null? type-members) - (raise-read-error-with-stx - (format "No member named ~a in type ~a" - (printable-key (ast:export/member-external (car export-binds))) - (printable-type (ast:export-type export))) - (ast:export/member-external (car export-binds)))] - [(null? export-binds) - (raise-read-error-with-stx - (format "Member ~a of type ~a was not exported" - (printable-key (tenv:member-name (car type-members))) - (printable-type (ast:export-type export))) - (ast-syntax export))] - [else - (let-values ([(matched non-matches) (partition-first (lambda (m) - (tenv-key=? (tenv:member-name m) - (ast:export/member-external (car export-binds)))) - type-members)] - [(lenv-entry) (lenv (ast:export/member-internal (car export-binds)))]) - (cond - [(not lenv-entry) - (raise-read-error-with-stx - (format "No static member named ~a" - (printable-key (ast:export/member-internal (car export-binds)))) - (ast:export/member-internal (car export-binds)))] - [(not matched) - (raise-read-error-with-stx - (format "No member named ~a in type ~a" - (printable-key (ast:export/member-external (car export-binds))) - (printable-type (ast:export-type export))) - (ast:export/member-external (car export-binds)))] - ;; if it's a method, then allow exporting a subtype - [(ast:type:method? (tenv:member-type matched)) - (if (<:_P lenv-entry (tenv:member-type matched)) - (loop non-matches (cdr export-binds)) - (raise-read-error-with-stx - (format "Exported static member ~a has type ~a which is not a subtype of ~a's type ~a" - (printable-key (ast:export/member-internal (car export-binds))) - (printable-type lenv-entry) - (printable-key (tenv:member-name matched)) - (printable-type (tenv:member-type matched))) - (ast:export/member-internal (car export-binds))))] - ;; for fields, we just do invariance until we get read-only fields - [else - (if (type-equal? lenv-entry (tenv:member-type matched)) - (loop non-matches (cdr export-binds)) - (raise-read-error-with-stx - (format "Exported static member ~a has type ~a which is not the same type as ~a's type ~a" - (printable-key (ast:export/member-internal (car export-binds))) - (printable-type lenv-entry) - (printable-key (tenv:member-name matched)) - (printable-type (tenv:member-type matched))) - (ast:export/member-internal (car export-binds))))]))]))) - - - - (define (extend-lenv-with-type-members lenv type) - (let ([type-entry (get-type-entry type)]) - (fold (lambda (m e) - (extend-fenv (tenv:member-name m) - (tenv:member-type m) - e)) - lenv - (tenv:type-members type-entry)))) - - (define (typecheck-supernew lenv withs supernew) - (let loop ([withs withs] - [args (ast:super-new-args supernew)] - [checked-args '()]) - (cond - [(and (null? withs) - (null? args)) - (copy-struct ast:super-new supernew - [ast:super-new-args (reverse checked-args)])] - [(null? withs) - (raise-read-error-with-stx - (format "No expected init slot declaration for super arg ~a" - (printable-key (ast:named/arg-name (car args)))) - (ast:named/arg-name (car args)))] - [(null? args) - (raise-read-error-with-stx - (format "Expected init slot ~a not used as super arg" - (printable-key (ast:formal-name (car withs)))) - (ast:formal-name (car withs)))] - [else - (let-values ([(matched non-matches) (partition-first (lambda (w) - (tenv-key=? (ast:formal-name w) - (ast:named/arg-name (car args)))) - withs)]) - (if (not matched) - (raise-read-error-with-stx - (format "No expected init slot declaration for super arg ~a" - (printable-key (ast:named/arg-name (car args)))) - (ast:named/arg-name (car args))) - (let ([first-arg (car args)]) - (let-values ([(e1 t1) (typecheck-expression lenv - (ast:formal-type matched) - (ast:named/arg-actual first-arg))]) - (loop non-matches - (cdr args) - (cons (copy-struct ast:named/arg first-arg - [ast:named/arg-actual e1]) - checked-args))))))]))) - - - (define (typecheck-members lenv selftype members) - (let loop ([members members] - [lenv lenv] - [ret '()]) - (cond - [(null? members) - (values (reverse ret) lenv)] - [(or (ast:class/member:field/formal? (car members)) - (ast:class/member:field? (car members))) - (let ([member (typecheck-member lenv selftype (car members))]) - (loop (cdr members) - (extend-fenv (get-class-member-name (car members)) - (get-class-member-type selftype (car members)) - lenv) - (cons member ret)))] - [(ast:class/member:method? (car members)) - (let-values ([(methods remainder) (span ast:class/member:method? members)]) - (let ([lenv (fold (lambda (m lenv) - (extend-fenv (get-class-member-name m) - (get-class-member-type selftype m) - lenv)) - lenv - methods)]) - (loop remainder - lenv - ;; I only through the reverse in to keep the order the same. - ;; it doesn't really matter. - (append (reverse (map (lambda (m) - (typecheck-member lenv selftype m)) - methods)) - ret))))]))) - - (define (typecheck-member lenv selftype member) - (match member - [(struct ast:class/member:field/formal (stx name type value)) - (if (not (type-valid? type)) - (raise-read-error-with-stx - "Type of init field is undefined" - (ast-syntax type))) - (if value - (let-values ([(e1 t1) (typecheck-expression lenv type value)]) - (copy-struct ast:class/member:field/formal member - [ast:class/member:field/formal-default e1])) - member)] - [(struct ast:class/member:field (stx name type value)) - (if (not (type-valid? type)) - (raise-read-error-with-stx - "Type of field is undefined" - (ast-syntax type))) - (let-values ([(e1 t1) (typecheck-expression lenv type value)]) - (copy-struct ast:class/member:field member - [ast:class/member:field-default e1]))] - [(struct ast:class/member:method (stx name type args body)) - (if (not (type-valid? type)) - (raise-read-error-with-stx - "Return type of method is undefined" - (ast-syntax type))) - (for-each (lambda (t) - (if (not (type-valid? t)) - (raise-read-error-with-stx - "Type of method argument is undefined" - (ast-syntax t)))) - (map ast:formal-type args)) - (let-values ([(e1 t1) (parameterize ([current-return-type type]) - (typecheck-expression (fold (lambda (arg fenv) - (extend-fenv (ast:formal-name arg) - (ast:formal-type arg) - fenv)) - lenv args) - type body))]) - (copy-struct ast:class/member:method member - [ast:class/member:method-body e1]))])) - - (define (get-class-member-name member) - (match member - [(struct ast:class/member:field/formal (stx name type value)) name] - [(struct ast:class/member:field (stx name type value)) name] - [(struct ast:class/member:method (stx name type args body)) name])) - - (define (get-class-member-type exptype member) - (match member - [(struct ast:class/member:field/formal (stx name type value)) - type] - [(struct ast:class/member:field (stx name type value)) - type] - [(struct ast:class/member:method (stx name type args body)) - (make-method-type stx exptype - (make-tuple-type stx (map ast:formal-type args)) - type)])) - - ) diff --git a/collects/honu/private/typechecker/typecheck-expression.ss b/collects/honu/private/typechecker/typecheck-expression.ss deleted file mode 100644 index 19ef3206b4..0000000000 --- a/collects/honu/private/typechecker/typecheck-expression.ss +++ /dev/null @@ -1,677 +0,0 @@ -(module typecheck-expression mzscheme - - (require (all-except (lib "list.ss" "srfi" "1") any) - (lib "contract.ss") - (lib "plt-match.ss") - (lib "struct.ss") - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../tools/general.ss" - "typecheck-parameters.ss" - "type-utils.ss") - - (provide/contract [typecheck-expression ((((syntax/c symbol?) . -> . (union ast:type? false/c)) - (union ast:type? false/c) - ast:expr?) - . ->* . - (ast:expr? - ast:type?))]) - - ;; lenv : ((syntax/c symbol?) . -> . (union ast:type false/c)) - ;; lexical environment (includes top-level bindings and - ;; binding for #'this if inside class or mixin) - ;; ctype : (union ast:type? false/c) - ;; type of context for expression - ;; expr : ast:expr? - ;; expression to typecheck - - (define (typecheck-expression lenv ctype expr) - (match expr - [(struct ast:expr:self (stx)) - (cond - [(lenv #'this) => (lambda (t) - (if (<:_P t ctype) - (values expr t) - (raise-honu-type-error stx ctype t)))] - [else (raise-read-error-with-stx - "Found use of 'this' outside of class or mixin" - stx)])] - [(struct ast:expr:tuple/select (stx slot arg)) - ;; changed to have a special "select" type that does the following: - ;; (type-select n t) <:_P (type-tuple args) if - ;; a) (>= (length args) n) - ;; b) (type-equal? (list-ref args (- n 1)) t) - ;; c) (list-ref args m) <:_P (type-top) for all m =/= n (vacuously true) - (let-values ([(e1 t1) (typecheck-expression lenv (make-ast:type:partial/tuple stx slot ctype) arg)]) - (if (not (ast:type:tuple? t1)) - (raise-read-error-with-stx "Tried to use select with non-tuple expression" stx)) - (let ([etype (list-ref (ast:type:tuple-elems t1) (- slot 1))]) - (values (copy-struct ast:expr:tuple/select expr - [ast:expr:tuple/select-arg e1]) - etype)))] - [(struct ast:expr:var (stx name)) - (cond - [(lenv name) => (lambda (t) - (if (<:_P t ctype) - (values expr t) - (raise-honu-type-error stx ctype t)))] - [else (raise-read-error-with-stx - (format "Unbound variable ~a" (syntax-e name)) - stx)])] - [(struct ast:expr:assign (stx lhs rhs)) - ;; the context type for the lhs is a vacuous one. - (let*-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax lhs)) lhs)] - [(e2 t2) (typecheck-expression lenv t1 rhs)]) - (let ([void-type (make-void-type stx)]) - (if (<:_P void-type ctype) - (values (copy-struct ast:expr:assign expr - [ast:expr:assign-lhs e1] - [ast:expr:assign-rhs e2]) - void-type) - (raise-honu-type-error stx ctype void-type))))] - [(struct ast:expr:apply (stx func arg)) - (let*-values ([(e1 t1) (typecheck-expression lenv (make-func-type (ast-syntax func) - (make-bottom-type (ast-syntax func)) - ctype) func)] - [(e2 t2) (typecheck-expression lenv (ast:type:function-input t1) arg)]) - (let ([ret-type (ast:type:function-output t1)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:apply expr - [ast:expr:apply-func e1] - [ast:expr:apply-arg e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(struct ast:expr:literal (stx type value)) - (if (<:_P type ctype) - (values expr type) - (raise-honu-type-error stx ctype type))] - [(struct ast:expr:unary/op (stx op op-stx _ arg)) - (case op - [(not) - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax arg)) arg)]) - (let ([ret-type (make-bool-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:unary/op expr - [ast:expr:unary/op-rator-type t1] - [ast:expr:unary/op-arg e1]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(minus) - (let-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax arg)) arg)]) - (if (not (ast:type:primitive? t1)) - (raise-read-error-with-stx - "Invalid type for argument to unary minus" - (ast-syntax arg)) - (let ([ret-type (case (ast:type:primitive-name t1) - [(int) (make-int-type (ast-syntax arg))] - [(float) (make-float-type (ast-syntax arg))] - [else (raise-read-error-with-stx - (format "Argument to unary minus must be int or float type, got ~a" - (printable-type t1)) - (ast-syntax arg))])]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:unary/op expr - [ast:expr:unary/op-rator-type t1] - [ast:expr:unary/op-arg e1]) - ret-type) - (raise-honu-type-error stx ctype ret-type)))))] - [else - (raise-read-error-with-stx - "Unknown operator" - op-stx)])] - [(struct ast:expr:binary/op (stx op op-stx _ larg rarg)) - (case op - ;; binary boolean operators - [(or and) - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-bool-type (ast-syntax rarg)) rarg)]) - (let ([ret-type (make-bool-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type (make-bool-type (ast-syntax larg))] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(clseq) - (let-values ([(e1 t1) (typecheck-expression lenv (make-any-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-any-type (ast-syntax rarg)) rarg)]) - (let ([ret-type (make-bool-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type (make-any-type (ast-syntax larg))] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(equal neq) - (let-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-top-type (ast-syntax rarg)) rarg)]) - (let ([ret-type (make-bool-type stx)] - [arg-type (cond - [(and (<:_P t1 (make-any-type (ast-syntax larg))) - (<:_P t2 (make-any-type (ast-syntax rarg)))) - (make-any-type (ast-syntax larg))] - [(check-prim-types-for-binop stx t1 t2) => (lambda (t) t)])]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type arg-type] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(le lt ge gt) - (let-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-top-type (ast-syntax rarg)) rarg)]) - (let ([ret-type (make-bool-type stx)] - [arg-type (check-prim-types-for-binop stx t1 t2)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type arg-type] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(plus) - (let-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-top-type (ast-syntax rarg)) rarg)]) - (let ([arg-type (check-prim-types-for-binop stx t1 t2)]) - (case (ast:type:primitive-name arg-type) - [(int float string) - (if (<:_P arg-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type arg-type] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - arg-type) - (raise-honu-type-error stx ctype arg-type))] - [else (raise-read-error-with-stx - "The plus operator requires both arguments to be of type int, type float, or type string" - stx)])))] - [(minus times div) - (let-values ([(e1 t1) (typecheck-expression lenv (make-top-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-top-type (ast-syntax rarg)) rarg)]) - (let ([arg-type (check-prim-types-for-binop stx t1 t2)]) - (case (ast:type:primitive-name arg-type) - [(int float) - (if (<:_P arg-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type arg-type] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - arg-type) - (raise-honu-type-error stx ctype arg-type))] - [else (raise-read-error-with-stx - "Arithmetic operator requires both arguments to be of type int or type float" - stx)])))] - [(mod) - (let-values ([(e1 t1) (typecheck-expression lenv (make-int-type (ast-syntax larg)) larg)] - [(e2 t2) (typecheck-expression lenv (make-int-type (ast-syntax rarg)) rarg)]) - (let ([ret-type (make-int-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:binary/op expr - [ast:expr:binary/op-rator-type (make-int-type (ast-syntax larg))] - [ast:expr:binary/op-left e1] - [ast:expr:binary/op-right e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [else - (raise-read-error-with-stx - "Unknown operator" - op-stx)])] - [(struct ast:expr:function (stx ret-type args body)) - (if (not (type-valid? ret-type)) - (raise-read-error-with-stx - "Return type of anonymous function is invalid" - (ast-syntax ret-type))) - (let ([conflicting-name (get-first-non-unique-name (map ast:formal-name args))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Variable name ~a used more than once in function arguments" - (printable-key conflicting-name)) - conflicting-name))) - (for-each (lambda (t) - (if (not (type-valid? t)) - (raise-read-error-with-stx - "Type of argument of anonymous function is invalid" - (ast-syntax t)))) - (map ast:formal-type args)) - ;; since we have explicit return type annotations now, we use them for the body's ctype and rtype. - (let ([body-lenv (fold (lambda (f e) - (extend-fenv (ast:formal-name f) - (ast:formal-type f) - e)) - lenv args)]) - (let-values ([(body _) (parameterize ([current-return-type ret-type]) - (typecheck-expression body-lenv ret-type body))]) - ;; we also have the lambda's return type be what was explicitly annotated instead of what we got back - (let ([lam-type (make-func-type stx (make-tuple-type stx (map ast:formal-type args)) ret-type)]) - (if (<:_P lam-type ctype) - (values (copy-struct ast:expr:function expr - [ast:expr:function-body body]) - lam-type) - (raise-honu-type-error stx ctype lam-type)))))] - [(struct ast:expr:if (stx test then else)) - (if else - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax test)) test)] - [(e2 t2) (typecheck-expression lenv ctype then)] - [(e3 t3) (typecheck-expression lenv ctype else)]) - ;; this should work, but I get the following: - ;; -- context expected 1 value, received 2 values: # # - ;; with the arrow going from values -> cond, so I'm going to rewrite as a nested-if for now. - (cond - ;; if we had a context type and got to this point, then both t2 and t3 must be related to it (either equal - ;; or subtypes), so use it as the type of the entire if expression. - ;; - ;; No, we can't do this. Think about the fact where we use an if expression on the left-hand side of a - ;; member access -- we need to get the most specific type back as the result, not the (vacuous) context - ;; type. If the branches are of unrelated types, then having a context type doesn't help us all the time. - ;; [ctype - ;; (values (copy-struct ast:expr:if expr - ;; [ast:expr:if-test e1] - ;; [ast:expr:if-then e2] - ;; [ast:expr:if-else e3]) - ;; ctype)] - ;; if there was no ctype, then we require either t2 <: t3 or t3 <: t2, and we'll pick the supertype. - [(<:_P t2 t3) - (values (copy-struct ast:expr:if expr - [ast:expr:if-test e1] - [ast:expr:if-then e2] - [ast:expr:if-else e3]) - t3)] - [(<:_P t3 t2) - (values (copy-struct ast:expr:if expr - [ast:expr:if-test e1] - [ast:expr:if-then e2] - [ast:expr:if-else e3]) - t2)] - ;; if we got to here, then there's no good type to use as the type of the entire if expression, so - ;; raise an error. - [else (raise-read-error-with-stx - "Branches of if statement are of unrelated types" - stx)])) - ;; if else is #f, there was no else branch, so the then branch must be of void type. - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax test)) test)] - [(e2 t2) (typecheck-expression lenv (make-void-type (ast-syntax then)) then)]) - (let ([ret-type (make-void-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:if expr - [ast:expr:if-test e1] - [ast:expr:if-then e2]) - ret-type) - (raise-read-error-with-stx - "Found if expression without else branch in non-void context" - stx)))))] - [(struct ast:expr:cast (stx obj type)) - (if (not (type-valid? type)) - (raise-read-error-with-stx - "Type argument of cast is not a valid type" - (ast-syntax type))) - (let-values ([(e1 t1) (typecheck-expression lenv (make-any-type (ast-syntax obj)) obj)]) - (if (<:_P type ctype) - (values (copy-struct ast:expr:cast expr - [ast:expr:cast-object e1]) - type) - (raise-honu-type-error stx ctype type)))] - [(struct ast:expr:isa (stx obj type)) - (if (not (type-valid? type)) - (raise-read-error-with-stx - "Type argument of isa is not a valid type" - (ast-syntax type))) - (let-values ([(e1 t1) (typecheck-expression lenv (make-any-type (ast-syntax obj)) obj)]) - (let ([ret-type (make-bool-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:isa expr - [ast:expr:isa-object e1]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(struct ast:expr:member (stx 'my _ name _)) - (cond - [(lenv name) - => - (lambda (t) - (if (ast:type:method? t) - (let ([fun-type (make-func-type (ast-syntax t) (ast:type:method-input t) (ast:type:method-output t))]) - (if (<:_P fun-type ctype) - (values (copy-struct ast:expr:member expr - [ast:expr:member-method? #t]) - fun-type) - (raise-honu-type-error stx ctype fun-type))) - (if (<:_P t ctype) - (values expr t) - (raise-honu-type-error stx ctype t))))] - [else (raise-read-error-with-stx - (format "Static member ~a not found" (syntax-e name)) - stx)])] - [(struct ast:expr:member (stx obj _ name _)) - (let-values ([(e1 t1) (typecheck-expression lenv (make-any-type (ast-syntax obj)) obj)]) - ;; if obj was something like error or return, which do not give us a valid type for - ;; getting the appropriate member... - (if (ast:type:bot? t1) - (raise-read-error-with-stx - "Attempt to access member of an expression which does not return" - stx)) - ;; if obj was null... - (if (ast:type:object:null? t1) - (raise-read-error-with-stx - "Null has no fields or methods" - stx)) - (let ([t (get-member-type t1 name)]) - (cond - [(ast:type:method? t) - (let ([fun-type (make-func-type (ast-syntax t) (ast:type:method-input t) (ast:type:method-output t))]) - (if (<:_P fun-type ctype) - (values (copy-struct ast:expr:member expr - [ast:expr:member-object e1] - [ast:expr:member-object-type t1] - [ast:expr:member-method? #t]) - fun-type) - (raise-honu-type-error stx ctype fun-type)))] - [t - (if (<:_P t ctype) - (values (copy-struct ast:expr:member expr - [ast:expr:member-object e1] - [ast:expr:member-object-type t1]) - t) - (raise-honu-type-error stx ctype t))] - [else (raise-read-error-with-stx - (format "Member ~a not found in type ~a" (syntax-e name) (printable-type t1)) - stx)])))] - [(struct ast:expr:new (stx class type args)) - (let ([class-entry (get-class-entry class)] - [new-type (if type type ctype)]) - ;; the following can only be triggered if the type annontation isn't a type - (if (and type (not (type-valid? type))) - (raise-read-error-with-stx - (format "Type annotation ~a on new statement is not a valid type" (printable-type new-type)) - (ast-syntax new-type))) - ;; the following two checks can only be triggered if there is no type annotation - (if (ast:type:top? new-type) - (raise-read-error-with-stx - "type of instantiation must be explicitly annotated" - stx)) - (if (not (<:_P new-type (make-any-type stx))) - (raise-read-error-with-stx - (format "new statement appears in context of non-interface type ~a" - (printable-type new-type)) - stx)) - ;; the class must implement a subtype of the type we're instantiating it at - (if (not (ormap (lambda (t) - (<:_P t new-type)) - (tenv:class-impls class-entry))) - (raise-read-error-with-stx - (format "class ~a does not implement a subtype of type ~a" - (printable-key class) - (printable-type new-type)) - stx)) - (let ([args (check-inits stx (lambda (e t) - (typecheck-expression lenv t e)) - (tenv:class-inits class-entry) args)]) - (if (<:_P new-type ctype) - (values (copy-struct ast:expr:new expr - [ast:expr:new-type new-type] - [ast:expr:new-args args]) - new-type) - (raise-honu-type-error stx ctype new-type))))] - [(struct ast:expr:while (stx cond body)) - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax cond)) cond)] - [(e2 t2) (typecheck-expression lenv (make-void-type (ast-syntax body)) body)]) - (let ([ret-type (make-void-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:while expr - [ast:expr:while-test e1] - [ast:expr:while-body e2]) - ret-type) - (raise-honu-type-error stx ctype ret-type))))] - [(struct ast:expr:cond (stx clauses else)) - (if else - (let-values ([(clauses types) (map-two-values (lambda (c) - (typecheck-cond-clause lenv ctype c)) - clauses)] - [(else etype) (typecheck-expression lenv ctype else)]) - (cond - ;; if ctype exists, just use it - ;; - ;; can't do this, see if for reasoning - ;; [ctype - ;; (values (copy-struct ast:expr:cond expr - ;; [ast:expr:cond-clauses clauses]) - ;; ctype)] - ;; otherwise find the most super type of all the branches - [(pick-super-type-from-list (cons etype types)) - => - (lambda (t) - (values (copy-struct ast:expr:cond expr - [ast:expr:cond-clauses clauses] - [ast:expr:cond-else else]) - t))] - ;; otherwise we're hosed for determining a type -- throw an error - [else - (raise-read-error-with-stx - "At least two branches of the cond statement have unrelated types" - stx)])) - ;; if else is #f, there was no else branch, so the cond clauses must be of void type. - (let-values ([(clauses types) (map-two-values (lambda (c) - (typecheck-cond-clause lenv - (make-void-type (ast-syntax c)) c)) - clauses)]) - (let ([ret-type (make-void-type stx)]) - (if (<:_P ret-type ctype) - (values (copy-struct ast:expr:cond expr - [ast:expr:cond-clauses clauses]) - ret-type) - (raise-read-error-with-stx - "Cond expression without an else branch found in non-void context" - stx)))))] - [(struct ast:expr:return (stx body)) - ;; returns don't return to their context, but to the context of the method or function call in which - ;; they were invoked. Because of this a) rtype must not be #f (else we're not in a method or function - ;; body) and b) the type of a return statement is the bottom type (same as error). - (if (current-return-type) - ;; we use rtype as the context type here, since that's the type that needs to be returned. - (let-values ([(e1 _) (typecheck-expression lenv (current-return-type) body)]) - ;; we don't need to check (bottom-type) <:_P ctype, because that's vacuously true. - (values (copy-struct ast:expr:return expr - [ast:expr:return-result e1]) - (make-bottom-type stx))) - (raise-read-error-with-stx - "Return statement found outside body of method or function" - stx))] - [(struct ast:expr:tuple (stx vals)) - (cond - [(ast:type:tuple? ctype) - ;; we have a tuple context type, so use its contents, but make - ;; sure it's the right length. - (if (not (= (length vals) (length (ast:type:tuple-elems ctype)))) - (raise-read-error-with-stx - (format "Expected tuple of length ~a, got tuple of length ~a" - (length vals) - (length (ast:type:tuple-elems ctype))) - stx)) - (let-values ([(vals types) (map-two-values (lambda (e t) - (typecheck-expression lenv t e)) - vals (ast:type:tuple-elems ctype))]) - (values (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems vals]) - (make-tuple-type stx types)))] - ;; we must be in hte context of a select expression, so - [(ast:type:partial/tuple? ctype) - (if (not (<= (ast:type:partial/tuple-position ctype) (length vals))) - (raise-read-error-with-stx - (format "Expected tuple of length at least ~a, got tuple of length ~a" - (ast:type:partial/tuple-position ctype) - (length vals)) - stx)) - (let-values ([(vals types) (map-two-values (lambda (e t) - (typecheck-expression lenv t e)) - vals (gen-top-except-for (length vals) - (ast:type:partial/tuple-position ctype) - (ast:type:partial/tuple-elem ctype)))]) - (values (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems vals]) - (make-tuple-type stx types)))] - ;; if we have the top type here, then we either a) don't care about the type or - ;; b) are going to check it after we return, so just do the simple thing -- since - ;; we have no knowledge about what's wanted, we just check each component with ctype. - [(ast:type:top? ctype) - (let-values ([(vals types) (map-two-values (lambda (e) - (typecheck-expression lenv - (make-top-type (ast-syntax e)) e)) - vals)]) - (values (copy-struct ast:expr:tuple expr - [ast:expr:tuple-elems vals]) - (make-tuple-type stx types)))] - [else (raise-read-error-with-stx - "Expected non-tuple expression (or tuple of length 1) here" - stx)])] - [(struct ast:expr:let (_ bindings body)) - (let*-values ([(bindings lenv) (map-and-fold (lambda (bind lenv) - (typecheck-binding lenv bind)) - lenv - bindings)] - [(e1 t1) (typecheck-expression lenv ctype body)]) - (values (copy-struct ast:expr:let expr - [ast:expr:let-bindings bindings] - [ast:expr:let-body e1]) - t1))] - [(struct ast:expr:sequence (_ effects value)) - (let-values ([(effects _) - (map-two-values - (lambda (e) - (typecheck-expression lenv (make-void-type (ast-syntax e)) e)) - effects)] - [(e1 t1) (typecheck-expression lenv ctype value)]) - (values (copy-struct ast:expr:sequence expr - [ast:expr:sequence-statements effects] - [ast:expr:sequence-result e1]) - t1))])) - - ;; bindings have no ctype because they're always in the void type context - ;; they return the elaborated binding and a new environment extended with the - ;; type of the bound variable. - (define (typecheck-binding lenv binding) - (match binding - [(struct ast:defn:binding (stx names types value)) - ;; make sure to remove all the #f for don't care arguments. - (let ([conflicting-name (get-first-non-unique-name (filter (lambda (n) n) names))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Variable name ~a used more than once in binding form" - (printable-key conflicting-name)) - conflicting-name))) - (for-each (lambda (n t) - (if (and (not (and (not n) - (ast:type:top? t))) - (not (type-valid? t))) - (raise-read-error-with-stx - "Type of locally bound variable is undefined" - (ast-syntax t)))) - names types) - (let-values ([(e1 t1) (typecheck-expression lenv (make-tuple-type (ast-syntax value) types) value)]) - (values (copy-struct ast:defn:binding binding - [ast:defn:binding-init e1]) - (fold (lambda (name type lenv) - (if name - (extend-fenv name type lenv) - lenv)) - lenv names types)))])) - - (define (typecheck-cond-clause lenv ctype clause) - (match clause - [(struct ast:cond/clause (stx pred rhs)) - (let-values ([(e1 t1) (typecheck-expression lenv (make-bool-type (ast-syntax pred)) pred)] - [(e2 t2) (typecheck-expression lenv ctype rhs)]) - (values (copy-struct ast:cond/clause clause - [ast:cond/clause-test e1] - [ast:cond/clause-result e2]) - t2))])) - - (define (check-prim-types-for-binop stx t1 t2) - (cond - [(and (ast:type:bot? t1) - (ast:type:primitive? t2)) - t2] - [(and (ast:type:primitive? t1) - (ast:type:bot? t2)) - t1] - [(and (ast:type:primitive? t1) - (ast:type:primitive? t2) - (type-equal? t1 t2)) - t1] - [else - (raise-read-error-with-stx - (format "Expected primitive types for binary operator, got ~a and ~a" - (printable-type t1) - (printable-type t2)) - stx)])) - - (define (check-inits stx type-fun inits new-args) - (let-values ([(new-args remaining-inits) - (map-and-fold (lambda (arg inits) - (let*-values ([(init remaining-inits) - (find-init inits (ast:named/arg-name arg))] - [(e1 t1) - (type-fun (ast:named/arg-actual arg) (tenv:init-type init))]) - (values (copy-struct ast:named/arg arg - [ast:named/arg-actual e1]) - remaining-inits))) - inits new-args)]) - (if (andmap tenv:init-optional? remaining-inits) - new-args - (raise-read-error-with-stx - (format "No value assigned for init arg ~a" - (printable-key (tenv:init-name (car remaining-inits)))) - stx)))) - - ;; find-inits takes the name of an init arg to find in a list of inits and - ;; returns both the init (if found) and the list minus that init - (define (find-init inits name) - (let loop ([inits inits] - [passed '()]) - (cond - [(null? inits) - (raise-read-error-with-stx - (format "class does not have an init arg with name ~a" - (printable-key name)) - name)] - [(tenv-key=? name (tenv:init-name (car inits))) - (values (car inits) - (append (reverse passed) (cdr inits)))] - [else - (loop (cdr inits) - (cons (car inits) passed))]))) - - - ;; assumes a non-empty list - (define (pick-super-type-from-list ts) - (define (pick-super-type-with-acc ts t) - (cond - ;; t is a super-type of all the other branches - [(andmap (lambda (t2) - (<:_P t2 t)) - ts) - t] - ;; if there's a type t2 in ts that is not equal to t - ;; but t <:_P t2, then recur with t2 instead. - [(find (lambda (t2) - (and (not (type-equal? t t2)) - (<:_P t t2))) - ts) - => - (lambda (t) - (pick-super-type-with-acc ts t))] - ;; there are no types in ts that are a super-type of t, - ;; but t is not equal to or a super-type of all the types - ;; in ts, we know that not all the types in the list are - ;; related and thus we fail. - [else #f])) - (pick-super-type-with-acc ts (car ts))) - - (define (gen-top-except-for n k t) - (cond - [(= n 0) (list)] - [(= k 1) (cons t (gen-top-except-for (- n 1) (- k 1) t))] - [else (cons (make-top-type #f) (gen-top-except-for (- n 1) (- k 1) t))])) - - ) diff --git a/collects/honu/private/typechecker/typecheck-parameters.ss b/collects/honu/private/typechecker/typecheck-parameters.ss deleted file mode 100644 index a35717b803..0000000000 --- a/collects/honu/private/typechecker/typecheck-parameters.ss +++ /dev/null @@ -1,13 +0,0 @@ -(module typecheck-parameters mzscheme - - (provide (all-defined)) - - ;; since the return type only changes when we go into a lambda in typecheck-expression, we - ;; make it a parameter also. - ;; - ;; rtype : (union ast:type? false/c) - ;; return type for method/function - - (define current-return-type (make-parameter #f)) - - ) diff --git a/collects/honu/private/typechecker/typecheck-utils.ss b/collects/honu/private/typechecker/typecheck-utils.ss deleted file mode 100644 index 0a2383718b..0000000000 --- a/collects/honu/private/typechecker/typecheck-utils.ss +++ /dev/null @@ -1,28 +0,0 @@ -(module typecheck-utils mzscheme - - (require (lib "contract.ss") - "../../ast.ss" - "../tools/general.ss" - "../../readerr.ss" - "type-utils.ss" - ) - - (provide/contract - [check-valid-type! (string? ast:type? . -> . void?)] - [check-valid-types! (string? (listof ast:type?) . -> . void?)] - ) - - ;; check-valid-type! : Name Type -> Void - ;; Raises an error if named type is not valid. - (define (check-valid-type! name type) - (if (not (type-valid? type)) - (raise-read-error-with-stx - (format "~s is undefined" name) - (ast-syntax type)))) - - ;; check-valid-types! : Name [Listof Type] -> Void - ;; Raises an error if any of the named types are not valid. - (define (check-valid-types! name types) - (for-each (curry check-valid-type! name) types)) - - ) diff --git a/collects/honu/private/typechecker/typechecker.ss b/collects/honu/private/typechecker/typechecker.ss deleted file mode 100644 index 682011a1e6..0000000000 --- a/collects/honu/private/typechecker/typechecker.ss +++ /dev/null @@ -1,251 +0,0 @@ -(module typechecker mzscheme - - (require (lib "contract.ss") - (lib "plt-match.ss") - (lib "struct.ss") - (prefix srfi1: (lib "list.ss" "srfi" "1")) - "../../ast.ss" - "../../readerr.ss" - "../../tenv.ss" - "../tools/general.ss" - "typecheck-utils.ss" - "typecheck-class-utils.ss" - "typecheck-expression.ss" - "typecheck-parameters.ss" - "type-utils.ss") - - (provide/contract [typecheck ((listof ast:defn?) - . -> . - (listof ast:defn?))] - [typecheck-defn (ast:defn? - . -> . - ast:defn?)]) - (define (typecheck defns) - (let loop ([defns defns] - [results '()]) - (cond - [(null? defns) (reverse results)] - ;; we allow functions to be mutually recursive in Algol-like fashion - ;; (i.e. if they are no intervening non-function definitions) - [(ast:defn:function? (car defns)) - (let-values ([(funcs remaining) (srfi1:span ast:defn:function? defns)]) - (loop remaining (append (typecheck-functions funcs) results)))] - [else (loop (cdr defns) (cons (typecheck-defn (car defns)) results))]))) - - (define (typecheck-functions funcs) - (define (check-function-type func) - (match func - [(struct ast:defn:function (stx name type args body)) - (check-valid-type! "function return type" type) - (let ([conflicting-name (get-first-non-unique-name (map ast:formal-name args))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Argument name ~a used more than once" - (printable-key conflicting-name)) - conflicting-name))) - (check-valid-types! "function argument type" (map ast:formal-type args)) - (make-func-type stx (make-tuple-type stx (map ast:formal-type args)) type)])) - ;; first we add the functions to the lexical environment so that when we typecheck - ;; the bodies, they'll be in scope. - (for-each (lambda (f) - (extend-lenv (ast:defn:function-name f) - (make-tenv:value (ast-syntax f) (check-function-type f)))) - funcs) - (let loop ([funcs funcs] - [new-funcs '()]) - (if (null? funcs) - ;; don't reverse it, because we want to keep these in the same order in typecheck, - ;; which will eventually reverse everything - new-funcs - (match (car funcs) - [(struct ast:defn:function (stx name type args body)) - (let-values - ([(e1 t1) - (parameterize ([current-return-type type]) - (typecheck-expression (srfi1:fold (lambda (a e) - (extend-fenv (ast:formal-name a) - (ast:formal-type a) - e)) - (wrap-lenv) - args) - type body))]) - (loop (cdr funcs) - (cons (copy-struct ast:defn:function (car funcs) - [ast:defn:function-body e1]) - new-funcs)))])))) - - ;; typecheck-bind-top : BindTop -> BindTop - ;; Typechecks a top-level binding and produces the annotated version. - (define (typecheck-bind-top bind-top) - (match bind-top - [(struct ast:defn:binding (stx names types value)) - (for-each (lambda (n t) - (if (not (and (not n) - (ast:type:top? t))) - (check-valid-type! "top-level bound variable type" t))) - names types) - (let-values ([(e1 t1) (typecheck-expression (wrap-lenv) (make-tuple-type stx types) value)]) - (for-each (lambda (n t) - (if n (extend-lenv n (make-tenv:value stx t)))) - names types) - (copy-struct ast:defn:binding bind-top - [ast:defn:binding-init e1]))])) - - ;; typecheck-iface : IFace -> IFace - ;; Typechecks an interface definition and produces the annotated version. - (define (typecheck-iface iface) - (match iface - [(struct ast:defn:iface (stx name supers members)) - (check-valid-types! "interface supertype" supers) - (let ([conflicting-name (get-first-non-unique-name (map ast:iface/member-name members))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Field/method name ~a used more than once" - (printable-key conflicting-name)) - conflicting-name))) - (for-each (lambda (m) - (typecheck-member-decl m)) - members) - iface])) - - ;; typecheck-class : Class -> Class - ;; Typechecks a class definition and produces the annotated version. - (define (typecheck-class class) - (match class - [(struct ast:defn:class (stx name type final? impls inits members exports)) - (check-valid-type! "class self-type" type) - (check-valid-types! "implemented type of class" impls) - (let ([conflicting-name (get-first-non-unique-name (append (map ast:formal-name inits) - (map ast:class/member-name members)))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Init/field/method name ~a used more than once" - (printable-key conflicting-name)) - conflicting-name))) - (check-valid-types! "init slot type" (map ast:formal-type inits)) - (let ([lenv (srfi1:fold (lambda (a e) - (extend-fenv (ast:formal-name a) - (ast:formal-type a) - e)) - (lambda (n) #f) - inits)]) - (let*-values ([(lenv) (extend-fenv #'this type (wrap-lenv))] - [(members lenv) (typecheck-members lenv type members)]) - (typecheck-exports lenv type impls exports) - (copy-struct ast:defn:class class - [ast:defn:class-members members])))])) - - ;; check-mixin-internal-names! : Mixin -> Void - ;; Raises an error if defined names in a mixin conflict with each other. - (define (check-mixin-internal-names! mixin) - (match mixin - [(struct ast:defn:mixin (stx name type arg-type final? impls inits withs - supernew members-before members-after exports)) - (let* ([arg-tentry (get-type-entry arg-type)] - [conflicting-name (get-first-non-unique-name (append (map tenv:member-name - (append (tenv:type-members arg-tentry) - (tenv:type-inherited arg-tentry))) - (map ast:formal-name inits) - (map ast:class/member-name - (append members-before - members-after))))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Init/field/method name ~a used more than once in mixin or conflicts with members of argument type" - (printable-key conflicting-name)) - (ast-syntax mixin))))])) - - ;; check-mixin-expected-init-names! : Mixin -> Void - ;; Raises an error if init arguments expected of mixin's argument contain conflicts - (define (check-mixin-expected-init-names! mixin) - (match mixin - [(struct ast:defn:mixin (stx name type arg-type final? impls inits withs - supernew members-before members-after exports)) - (let ([conflicting-name (get-first-non-unique-name (map ast:formal-name withs))]) - (if conflicting-name - (raise-read-error-with-stx - (format "Init name ~a used more than once in expected init slots" - (printable-key conflicting-name)) - conflicting-name)))])) - - ;; check-distinct-names! : String [Listof Identifier] -> Void - ;; Raises an error if any of the names are the same. - (define (check-distinct-names! desc names) - (cond - [(check-duplicate-identifier names) => - (lambda (name) - (raise-read-error-with-stx (format "Duplicate name ~s found in ~s." name desc) name))] - [else (void)])) - - ;; check-distinct-types! : String [Listof Honu:Type] -> Void - ;; Raises an error if any of the types are the same. - (define (check-distinct-types! desc types) - (check-distinct-names! desc (map ast:type:object:iface-name types))) - - ;; typecheck-mixin : Mixin -> Mixin - ;; Typechecks a mixin definition and produces the annotated version. - (define (typecheck-mixin mixin) - (match mixin - [(struct ast:defn:mixin (stx name type arg-type final? impls inits withs - supernew members-before members-after exports)) - - (define members (append members-before members-after)) - (define member-names (map ast:class/member-name members)) - (define init-names (map ast:formal-name inits)) - (define super-member-names (type-member-names arg-type)) - - (check-valid-type! "mixin argument type" arg-type) - (check-valid-type! "mixin result type" type) - (check-valid-types! "mixin implemented type" impls) - (check-valid-types! "init slot type" (map ast:formal-type inits)) - (check-valid-types! "superclass init slot type" (map ast:formal-type withs)) - (check-distinct-types! "mixin implemented types" impls) - (check-distinct-names! "internally visible member/init names" - (append super-member-names init-names member-names)) - (check-distinct-names! "superclass init slot names" - (map ast:formal-name withs)) - - (let*-values ([(lenv) (wrap-lenv)] - [(lenv) (extend-fenv #'this type lenv)] - [(lenv) (srfi1:fold extend-fenv-ast:formal lenv inits)] - [(members-before lenv) (typecheck-members lenv type members-before)] - [(supernew) (typecheck-supernew lenv withs supernew)] - [(lenv) (extend-lenv-with-type-members lenv arg-type)] - [(members-after lenv) (typecheck-members lenv type members-after)]) - (typecheck-exports lenv type impls exports) - (copy-struct ast:defn:mixin mixin - [ast:defn:mixin-pre-members members-before] - [ast:defn:mixin-super-new supernew] - [ast:defn:mixin-post-members members-after]))])) - - ;; typecheck-subclass : Subclass -> Subclass - ;; Typechecks a subclass definition and produces the annotated version. - (define (typecheck-subclass subclass) - (match subclass - ;; we basically do all the checks when we create the tenv entry for the subclass (plus typechecking the base - ;; class and mixin), so no need to check again. - [(struct ast:defn:subclass (_ _ _ _)) - subclass])) - - ;; typecheck-defn : Defn -> Defn - ;; Typechecks a top-level definition and produces the annotated version. - (define (typecheck-defn defn) - (cond - [(ast:defn:binding? defn) (typecheck-bind-top defn)] - [(ast:defn:iface? defn) (typecheck-iface defn)] - [(ast:defn:class? defn) (typecheck-class defn)] - [(ast:defn:mixin? defn) (typecheck-mixin defn)] - [(ast:defn:subclass? defn) (typecheck-subclass defn)] - [else (raise-read-error-with-stx - "Haven't implemented typechecking for that type of definition yet." - (ast-syntax defn))])) - - (define (typecheck-member-decl member) - (match member - [(struct ast:iface/member:field (stx name type)) - (check-valid-type! "field type" type)] - [(struct ast:iface/member:method (stx name type args)) - (check-valid-type! "method return type" type) - (check-valid-types! "method argument type" args)])) - - ) diff --git a/collects/honu/readerr.ss b/collects/honu/readerr.ss deleted file mode 100644 index 6d99c59979..0000000000 --- a/collects/honu/readerr.ss +++ /dev/null @@ -1,20 +0,0 @@ -(module readerr mzscheme - - (require (lib "readerr.ss" "syntax")) - - (provide raise-read-error-with-stx) - ;; Yes, this is misleading for now. I'll rename it later. - ;; (define (raise-read-error-with-stx str stx) - ;; (raise-syntax-error #f str stx)) - - ;; Forget it, this gives you less extra crap with your error message. - ;; I'd need to decide what to put in those places instead, so at the - ;; moment we'll keep it a read error. - (define (raise-read-error-with-stx str stx) - (raise-read-error str - (syntax-source stx) - (syntax-line stx) - (syntax-column stx) - (syntax-position stx) - (syntax-span stx))) - ) diff --git a/collects/honu/run-tests.ss b/collects/honu/run-tests.ss deleted file mode 100644 index 29c20830fe..0000000000 --- a/collects/honu/run-tests.ss +++ /dev/null @@ -1,21 +0,0 @@ -(module run-tests mzscheme - - (require "honu-tests.ss" - ) - - (provide test/text test/graphical) - - (define (test/text) - ((dynamic-require '(planet "text-ui.ss" ("schematics" "schemeunit.plt" 1 1)) 'test/text-ui) - honu-tests)) - - (define (test/graphical) - ((dynamic-require '(planet "graphical-ui.ss" ("schematics" "schemeunit.plt" 1 1)) 'test/graphical-ui) - honu-tests)) - - ) - - - - - \ No newline at end of file diff --git a/collects/honu/tenv-utils.ss b/collects/honu/tenv-utils.ss deleted file mode 100644 index e5a445ab4e..0000000000 --- a/collects/honu/tenv-utils.ss +++ /dev/null @@ -1,561 +0,0 @@ -(module tenv-utils mzscheme - - (require "readerr.ss" - "ast.ss" - "parameters.ss" - "tenv.ss" - "private/tools/general.ss" - "private/typechecker/type-utils.ss" - (lib "plt-match.ss") - (lib "struct.ss") - (lib "list.ss" "srfi" "1")) - - (define (make-struct-type-decls inits mfidefns) - (define (convert-to-decl d) - (cond - ;; can come from inits - [(ast:formal? d) - (make-ast:iface/member:field (ast-syntax d) - (ast:formal-name d) - (ast:formal-type d))] - ;; can come from mdidefns - [(ast:class/member:field/formal? d) - (make-ast:iface/member:field (ast-syntax d) - (ast:class/member-name d) - (ast:class/member:field/formal-type d))] - [(ast:class/member:field? d) - (make-ast:iface/member:field (ast-syntax d) - (ast:class/member-name d) - (ast:class/member:field-type d))] - [(ast:class/member:method? d) - (make-ast:iface/member:method (ast-syntax d) - (ast:class/member-name d) - (ast:class/member:method-return-type d) - (map ast:formal-type (ast:class/member:method-formals d)))])) - (map convert-to-decl (append inits mfidefns))) - - (define (make-struct-export typ inits mdidefns members) - (define (grab-name d) - (cond - ;; can come from members - [(tenv:member? d) (tenv:member-name d)] - ;; can come from inits - [(ast:formal? d) (ast:formal-name d)] - ;; can come from mdidefns - [(ast:class/member? d) (ast:class/member-name d)])) - (let ([binds (map (lambda (m) - (let ([name (grab-name m)]) - (make-ast:export/member #f name name))) (append inits mdidefns members))]) - (make-ast:export #f typ binds))) - - (define (tenv-create-error skipped) - ;; only subclasses and substructs can be skipped, so if the base of one of them - ;; is in the skipped list as well, then we have a cycle. If not, then there's - ;; some missing definition. - ;; - ;; well, this isn't true anymore, so check to see if it's an iface first, which - ;; is the other possibility for skipping. We need to check a similar kind of - ;; thing to see if the type hierarchy is a cycle or there's just something missing. - ;; - ;; FIXME: This function almost certainly does not always give the correct error message - ;; (for example, it may give a cycle error when it turns out that the first thing - ;; in the skipped list just depends on something else which just had stuff missing, - ;; so there should have been a definitions needed missing error. Will revisit later. - (if (ast:defn:iface? (car skipped)) - (let ([supers (ast:defn:iface-supers (car skipped))]) - (if (find (lambda (d) - (cond - [(ast:defn:iface? d) (s:member (ast:defn:iface-name d) supers tenv-key=?)] - [else #f])) - (cdr skipped)) - (raise-read-error-with-stx - (format "Type ~a is involved in a type hierarchy cycle" - (printable-key (ast:defn:iface-name (car skipped)))) - (ast:defn:iface-name (car skipped))) - (raise-read-error-with-stx - (format "At least one supertype of type ~a is missing" - (printable-key (ast:defn:iface-name (car skipped)))) - (ast:defn:iface-name (car skipped))))) - (let ([class-name (cond - [(ast:defn:subclass? (car skipped)) (ast:defn:subclass-name (car skipped))] - [(ast:defn:substructure? (car skipped)) (ast:defn:substructure-name (car skipped))])] - [base-name (cond - [(ast:defn:subclass? (car skipped)) (ast:defn:subclass-base (car skipped))] - [(ast:defn:substructure? (car skipped)) (ast:defn:substructure-super-class (car skipped))])]) - (if (find (lambda (d) - (cond - [(ast:defn:subclass? d) (tenv-key=? base-name (ast:defn:subclass-name d))] - [(ast:defn:substructure? d) (tenv-key=? base-name (ast:defn:substructure-name d))] - [else #f])) - (cdr skipped)) - (raise-read-error-with-stx - (format "Class ~a is involved in a class hierarchy cycle" (printable-key class-name)) - class-name) - (raise-read-error-with-stx - (format "Definitions needed for definition of class ~a are missing" (printable-key class-name)) - class-name))))) - - (provide add-defns-to-tenv add-defn-to-tenv) - (define (add-defns-to-tenv defns) - (let loop ([defns defns] - [skipped '()] - [changed? #f] - [new-defns '()]) - (cond - ;; we're done, so return the new defns - [(and (null? defns) (null? skipped)) - (reverse new-defns)] - ;; we skipped some, so go back and check those. - [(null? defns) - (if changed? - (loop skipped '() #f new-defns) - ;; we didn't change anything on the last run, - ;; so we must either have a cycle in the class graph - ;; or there are missing definitions. Raise an - ;; appropriate error for the first definition. - (tenv-create-error skipped))] - ;; for functions and top level bindings, we - ;; don't add them here, so just skip them. - [(or (ast:defn:function? (car defns)) - (ast:defn:binding? (car defns))) - (loop (cdr defns) skipped #t (cons (car defns) new-defns))] - [(ast:defn:iface? (car defns)) - (let loop2 ([supers (map ast:type:object:iface-name (ast:defn:iface-supers (car defns)))]) - (cond - ;; if we went through all the supers with them being defined, - ;; then we can add this type as well. - [(null? supers) - (loop (cdr defns) skipped #t (cons (add-defn-to-tenv (car defns)) new-defns))] - ;; if there is an entry, we check to make sure it's a type, and - ;; if it is, then we continue looping in the inner loop - [(get-tenv-entry (car supers)) - => - (lambda (e) - (if (not (tenv:type? e)) - (raise-read-error-with-stx - (format "~a is not a type" (printable-key (car supers))) - (car supers)) - (loop2 (cdr supers))))] - ;; if there is no entry, then we can't add this type yet, so - ;; recur on the outer loop with this type being skipped. - [else - (loop (cdr defns) (cons (car defns) skipped) changed? new-defns)]))] - ;; for classes and mixins, we don't use the tenv to create - ;; their entries, so we just run them through as we hit them. - [(or (ast:defn:class? (car defns)) - (ast:defn:mixin? (car defns))) - (loop (cdr defns) skipped #t (cons (add-defn-to-tenv (car defns)) new-defns))] - ;; for structs, we will get back a list of two things: the new type - ;; and the new class definition, so append those onto new-defns - [(ast:defn:structure? (car defns)) - (match (car defns) - [(struct ast:defn:structure (stx name type final? impls inits members exports)) - (let ([new-iface (make-ast:defn:iface stx (ast:type:object:iface-name type) (list) - (make-struct-type-decls inits members))] - [new-class (make-ast:defn:class stx name type final? (cons type impls) inits members - (cons (make-struct-export type inits members (list)) exports))]) - (loop (cdr defns) skipped #t (cons (add-defn-to-tenv new-class) - (cons (add-defn-to-tenv new-iface) new-defns))))])] - ;; for subclasses, we check to make sure the base (and its self-type) and - ;; the mixin (and its arg-type) are in the tenv. If not, skip it. - ;; Give appropriate errors for each thing that can go wrong. - [(ast:defn:subclass? (car defns)) - (let* ([base (get-tenv-entry (ast:defn:subclass-base (car defns)))] - [selftype (if (and base (tenv:class? base)) - (get-tenv-entry (ast:type:object:iface-name (tenv:class-sub-type base))) - #f)] - [mixin (get-tenv-entry (ast:defn:subclass-mixin (car defns)))] - [argtype (if (and mixin (tenv:mixin? mixin)) - (get-tenv-entry (ast:type:object:iface-name (tenv:mixin-arg-type mixin))) - #f)]) - (cond - [(and base (not (tenv:class? base))) - (raise-read-error-with-stx - "Base class for subclass definition is not a class" - (ast:defn:subclass-base (car defns)))] - [(and selftype (not (tenv:type? selftype))) - (raise-read-error-with-stx - "Selftype for class is not a type" - (ast-syntax (tenv:class-sub-type base)))] - [(and mixin (not (tenv:mixin? mixin))) - (raise-read-error-with-stx - "Mixin for subclass definition is not a mixin" - (ast:defn:subclass-mixin (car defns)))] - [(and argtype (not (tenv:type? argtype))) - (raise-read-error-with-stx - "Argument type for mixin is not a type" - (ast-syntax (tenv:mixin-arg-type mixin)))] - [(and base selftype mixin argtype) - ;; if the base is final, then we can't extend it. - (if (tenv:class-final? base) - (raise-read-error-with-stx - (format "Cannot apply mixin to final class ~a" - (printable-key base)) - base)) - ;; if the base's selftype does not match the mixin's argtype, - ;; we cannot apply the mixin to the base. - (if (not (<:_P (tenv:class-sub-type base) (tenv:mixin-arg-type mixin))) - (raise-read-error-with-stx - (format "Class ~a (~a) is not of an appropriate type (~a) for mixin ~a" - (printable-key (ast:defn:subclass-base (car defns))) - (printable-type (tenv:class-sub-type base)) - (printable-type (tenv:mixin-arg-type mixin)) - (printable-key (ast:defn:subclass-mixin (car defns)))) - (ast:defn:subclass-base (car defns)))) - (loop (cdr defns) skipped #t (cons (add-defn-to-tenv (car defns)) new-defns))] - ;; if we get here, we cannot yet make the entry for this subclass, - ;; so skip it. - [else - (loop (cdr defns) (cons (car defns) skipped) changed? new-defns)]))] - ;; for substructs, we just deconstruct it and then let the subclass logic catch any problems. - ;; we do a couple of checks, because getting the type right for the substruct requires having - ;; the argtype of the substruct. - [(ast:defn:substructure? (car defns)) - (match (car defns) - [(struct ast:defn:substructure (stx name type base arg-type final? impls inits withs super-new - members-before members-after exports)) - (let ([argtype (get-tenv-entry (ast:type:object:iface-name arg-type))]) - (cond - [(and argtype (not (tenv:type? argtype))) - (raise-read-error-with-stx - "Type at which we are extending is not a type" - (ast-syntax arg-type))] - [argtype - (let* ([new-iface (make-ast:defn:iface stx (ast:type:object:iface-name type) (list arg-type) - (make-struct-type-decls inits - (append members-before members-after)))] - [mixin-name (datum->syntax-object name (string->symbol - (string-append "$" (symbol->string (printable-key name)))) - name)] - [new-mixin (make-ast:defn:mixin stx mixin-name type arg-type final? (cons type impls) inits withs - super-new members-before members-after - (cons (make-struct-export type - inits - (append members-before members-after) - (tenv:type-members argtype)) - exports))] - [new-sclass (make-ast:defn:subclass stx name base mixin-name)]) - (loop (cons new-sclass (cdr defns)) skipped #t (cons (add-defn-to-tenv new-mixin) - (cons (add-defn-to-tenv new-iface) new-defns))))] - [else - (loop (cdr defns) (cons (car defns) skipped) changed? new-defns)]))])]))) - - (define (check-super-for-members name members super-name) - (match (get-tenv-entry super-name) - [(struct tenv:type (_ _ super-members super-inherited)) - ;; here we make sure to use both defined members and inherited members - (let loop ([super-members (append super-members super-inherited)] - [inherited '()]) - (cond - ;; we've checked all the super members - [(null? super-members) - (reverse inherited)] - ;; if we find a member of the subtype that matches the currently inspected member of - ;; the supertype... - [(find (lambda (m) - (tenv-key=? (tenv:member-name m) - (tenv:member-name (car super-members)))) - members) - => - (lambda (m) - ;; if we eventually allow co-/contra-variance here, this is where - ;; we'd do it. - (if (ast:type:method? (tenv:member-type (car super-members))) - (if (<:_P (tenv:member-type m) (tenv:member-type (car super-members))) - (loop (cdr super-members) inherited) - (raise-read-error-with-stx - (format "Type ~a defines member ~a with type ~a, is not a subtype of type ~a as defined in supertype ~a" - (printable-key name) - (printable-key (tenv:member-name m)) - (printable-type (tenv:member-type m)) - (printable-type (tenv:member-type (car super-members))) - (printable-key super-name)) - (tenv:member-stx m))) - ;; this handles mutable fields -- we don't have immutable fields yet - (if (type-equal? (tenv:member-type m) (tenv:member-type (car super-members))) - (loop (cdr super-members) inherited) - (raise-read-error-with-stx - (format "Type ~a defines member ~a with type ~a, was defined with type ~a in supertype ~a" - (printable-key name) - (printable-key (tenv:member-name m)) - (printable-type (tenv:member-type m)) - (printable-type (tenv:member-type (car super-members))) - (printable-key super-name)) - (tenv:member-stx m)))))] - ;; if there was no match, then this is one we inherited and for which we did not give - ;; an explicit declaration. - [else - (loop (cdr super-members) (cons (cons super-name (car super-members)) inherited))]))])) - - (define (mangle-disp-type iface member) - (let ([member-type (tenv:member-type member)]) - (if (ast:type:method? member-type) - (copy-struct tenv:member member - [tenv:member-type (make-method-type (ast-syntax member-type) - iface - (ast:type:method-input member-type) - (ast:type:method-output member-type))]) - member))) - - (define (type-equal-modulo-disp? t1 t2) - (let ([t1 (if (ast:type:method? t1) - (make-func-type (ast-syntax t1) - (ast:type:method-input t1) - (ast:type:method-output t1)) - t1)] - [t2 (if (ast:type:method? t2) - (make-func-type (ast-syntax t2) - (ast:type:method-input t2) - (ast:type:method-output t2)) - t2)]) - (type-equal? t1 t2))) - - (define (check-and-remove-duplicate-members subtype inherited-members) - (let loop ([inherited-members inherited-members] - [unique-members '()]) - (if (null? inherited-members) - (reverse unique-members) - (let ([current-member (cdr (car inherited-members))]) - (let-values ([(matching-members rest-members) - (partition (lambda (p) - (tenv-key=? (tenv:member-name current-member) - (tenv:member-name (cdr p)))) - (cdr inherited-members))]) - (let loop2 ([matching-members matching-members]) - (cond - [(null? matching-members) - (loop rest-members (cons (mangle-disp-type (make-iface-type subtype subtype) - current-member) - unique-members))] - ;; members coming from supers that are _not_ redefined must be exactly equal - ;; (modulo the dispatch arguments of methods) - ;; - ;; doesn't matter which we keep, so we'll just keep the first one that matched. - [(type-equal-modulo-disp? (tenv:member-type current-member) - (tenv:member-type (cdr (car matching-members)))) - (loop2 (cdr matching-members))] - [else - (raise-read-error-with-stx - (format "For type ~a, supertype ~a has type ~a for member ~a, whereas supertype ~a has type ~a" - (printable-key subtype) - (printable-key (car (car inherited-members))) - (printable-type (tenv:member-type current-member)) - (printable-key (tenv:member-name current-member)) - (printable-key (car (car matching-members))) - (printable-type (tenv:member-type (cdr (car matching-members))))) - subtype)]))))))) - - (define (add-defn-to-tenv defn) - (match defn - ;; for types, we need to recur over our supertypes, make sure that we don't have any definitions that countermand - ;; those in our super classes (which will also make sure that our superclass definitions are consistent), and - ;; then we will add any member definitions in them that are _not_ declared in this type. - ;; - ;; If we get here, we know that all the supers are in the tenv and are type entries, so we can use - ;; get-type-entry safely. - [(struct ast:defn:iface (src-stx name supers members)) - ;; we have to do this because members of the type can refer to the type itself. - ;; this is only for <:_P checks. - (extend-tenv name - (make-tenv:type src-stx supers '() '())) - (let* ([tenv-members (convert-members (make-iface-type name name) members)] - [inherited-decls - (apply append (map (lambda (n) (check-super-for-members name tenv-members n)) - (map ast:type:object:iface-name supers)))] - [unique-inherited - ;; remove duplicate entries for the same member name, making sure they match. - (check-and-remove-duplicate-members name inherited-decls)]) - - (extend-tenv-without-checking name - (make-tenv:type src-stx supers tenv-members unique-inherited)) - defn)] - ;; for classes and mixins, just add a new appropriate entry. - [(struct ast:defn:class (src-stx name t f? impls inits defns _)) - (extend-tenv name (make-tenv:class src-stx t impls - (get-inits inits defns) - f? #f)) - defn] - [(struct ast:defn:mixin (src-stx name type arg-type final? impls inits - withs _ defns-before defns-after _)) - (extend-tenv name (make-tenv:mixin src-stx arg-type type impls - (get-inits inits - (append defns-before - defns-after)) - withs final?)) - defn] - ;; all the heavy lifting of subclasses is in generate-subclass-tenv, - ;; which does things like make sure that the withs of the mixin are satisfied - ;; by the base, collects all the inits needed for the resulting class, etc. - [(struct ast:defn:subclass (src-stx name base mixin)) - (extend-tenv name (generate-subclass-tenv defn)) - defn])) - - (define (convert-members iface members) - (let loop ([members members] - [converted '()]) - (if (null? members) - (reverse converted) - (match (car members) - [(struct ast:iface/member:field (stx name type)) - (loop (cdr members) - (cons (make-tenv:member stx name type) converted))] - [(struct ast:iface/member:method (stx name type arg-types)) - (loop (cdr members) - (cons (make-tenv:member stx name (make-method-type stx - iface - (make-tuple-type stx arg-types) - type)) - converted))])))) - - (define (get-inits inits defns) - (let ([init-fields (filter (lambda (d) - (ast:class/member:field/formal? d)) - defns)]) - (append (map (lambda (i) - (make-tenv:init (ast:formal-name i) - (ast:formal-type i) - #f)) - inits) - (map (lambda (d) - (make-tenv:init (ast:class/member-name d) - (ast:class/member:field/formal-type d) - (not (false? (ast:class/member:field/formal-default d))))) - init-fields)))) - - (define (generate-subclass-tenv defn) - (let ([base (get-class-entry (ast:defn:subclass-base defn))] - [mixin (get-mixin-entry (ast:defn:subclass-mixin defn))]) - (let ([new-inits (remove-used-inits defn - (tenv:class-inits base) - (tenv:mixin-withs mixin))]) - (make-tenv:class (ast-syntax defn) - (tenv:mixin-sub-type mixin) - (tenv:mixin-impls mixin) - (append (tenv:mixin-inits mixin) - new-inits) - (tenv:mixin-final? mixin) - (ast:defn:subclass-base defn))))) - - (define (remove-used-inits defn old-inits withs) - (let loop ([old-inits old-inits] - [withs withs] - [new-inits '()]) - (if (null? old-inits) - (if (not (null? withs)) - (raise-read-error-with-stx - (format "Class ~a does not have an init arg ~a with the correct type" - (printable-key (ast:defn:subclass-base defn)) - (printable-key (ast:formal-name (car withs)))) - (ast:defn:subclass-base defn)) - (reverse new-inits)) - (let* ([curr (car old-inits)] - [index (list-index (lambda (w) - (tenv-key=? (ast:formal-name w) (tenv:init-name curr))) - withs)]) - (if index - (if (<:_P (ast:formal-type (list-ref withs index)) (tenv:init-type curr)) - (loop (cdr old-inits) - (append (take withs index) - (drop withs (+ index 1))) - new-inits) - (raise-read-error-with-stx - (format "Mixin ~a needs an incompatible type for init arg ~a" - (printable-key (ast:defn:subclass-mixin defn)) - (printable-key (ast:formal-name (car withs)))) - (ast:defn:subclass-mixin defn))) - (loop (cdr old-inits) - withs - (cons curr new-inits))))))) - - (provide display-lenv display-current-lenv display-tenv display-current-tenv) - (define (display-current-lenv) - (display-lenv (current-lexical-environment))) - (define (display-lenv lenv) - (tenv-for-each lenv - (lambda (k v) - (display (format "~a = ~a~%" - (printable-key k) - (printable-type (tenv:value-type v))))))) - - (define (display-current-tenv) - (display-lenv (current-type-environment))) - (define (display-tenv tenv) - (tenv-for-each tenv - (lambda (k v) - (display (format "~a = " (printable-key k))) - (display-tenv-entry v)))) - - (define (display-tenv-entry entry) - (match entry - [(struct tenv:type (_ supers members inherited)) - (display (format "type {~%")) - (display (format " supers = ")) - (if (null? supers) (display "(none)")) - (for-each (lambda (s) (display (format "~a " (printable-type s)))) supers) - (newline) - (display (format " members = ")) - (if (null? members) (display "(none)")) - (newline) - (for-each (lambda (m) - (match m - [(struct tenv:member (_ name type)) - (display (format " ~a : ~a~%" - (printable-key name) - (printable-type type)))])) - members) - (display (format " inherited members = ")) - (if (null? inherited) (display "(none)")) - (newline) - (for-each (lambda (m) - (match m - [(struct tenv:member (_ name type)) - (display (format " ~a : ~a~%" - (printable-key name) - (printable-type type)))])) - inherited) - (display (format "}~%"))] - [(struct tenv:class (_ sub-type impls inits final? super)) - (display (format "class {~%")) - (display (format " final? = ~a~%" (if final? "yes" "no"))) - (display (format " super = ~a~%" (if super (printable-key super) "(none)"))) - (display (format " sub-type = ~a~%" (printable-type sub-type))) - (display (format " impls = ")) - (for-each (lambda (s) (display (format "~a " (printable-type s)))) impls) - (if (null? impls) (display "(none)")) - (newline) - (display (format " inits = ")) - (if (null? inits) (display "(none)")) - (newline) - (for-each (lambda (i) (display (format " ~a : ~a ~a~%" - (printable-key (tenv:init-name i)) - (printable-type (tenv:init-type i)) - (if (tenv:init-optional? i) "(opt)" "")))) - inits) - (display (format "}~%"))] - [(struct tenv:mixin (_ arg-type sub-type impls inits withs final?)) - (display (format "mixin {~%")) - (display (format " final? = ~a~%" (if final? "yes" "no"))) - (display (format " arg-type = ~a~%" (printable-type arg-type))) - (display (format " sub-type = ~a~%" (printable-type sub-type))) - (display (format " impls = ")) - (for-each (lambda (s) (display (format "~a " (printable-type s)))) impls) - (if (null? impls) (display "(none)")) - (newline) - (display (format " inits = ")) - (if (null? inits) (display "(none)")) - (newline) - (for-each (lambda (i) (display (format " ~a : ~a ~a~%" - (printable-key (tenv:init-name i)) - (printable-type (tenv:init-type i)) - (if (tenv:init-optional? i) "(opt)" "")))) - inits) - (display (format " withs = ")) - (if (null? withs) (display "(none)")) - (newline) - (for-each (lambda (i) (display (format " ~a : ~a ~a~%" - (printable-key (tenv:init-name i)) - (printable-type (tenv:init-type i)) - (if (tenv:init-optional? i) "(opt)" "")))) - withs) - (display (format "}~%"))])) - ) diff --git a/collects/honu/tenv.ss b/collects/honu/tenv.ss deleted file mode 100644 index fd60c09292..0000000000 --- a/collects/honu/tenv.ss +++ /dev/null @@ -1,251 +0,0 @@ -(module tenv mzscheme - - (require (all-except (lib "list.ss" "srfi" "1") any) - (lib "boundmap.ss" "syntax") - (lib "contract.ss") - "ast.ss" - "parameters.ss" - "readerr.ss") - - (define-struct tenv:entry (stx) #f) - - (define-struct tenv:init (name type optional?) #f) - - (define-struct tenv:member (stx name type) #f) - - ;; members will be a hashtable from member names to types - ;; -- if I ever get around to it - (define-struct (tenv:type tenv:entry) (supers members inherited) #f) - (define-struct (tenv:class tenv:entry) (sub-type impls inits final? super) #f) - (define-struct (tenv:mixin tenv:entry) (arg-type sub-type impls inits - withs final?) #f) - ;; this is for top-level function and value bindings - (define-struct (tenv:value tenv:entry) (type) #f) - - (define builtin-list - (list (cons #'error (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:bot #f))) - (cons #'printString (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:tuple #f '()))) - (cons #'printLine (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:tuple #f '()))) - (cons #'readChar (make-ast:type:function #f - (make-ast:type:tuple #f '()) - (make-ast:type:primitive #f 'char))) - (cons #'readLine (make-ast:type:function #f - (make-ast:type:tuple #f '()) - (make-ast:type:primitive #f 'string))) - (cons #'intToString (make-ast:type:function #f - (make-ast:type:primitive #f 'int) - (make-ast:type:primitive #f 'string))) - (cons #'floatToString (make-ast:type:function #f - (make-ast:type:primitive #f 'float) - (make-ast:type:primitive #f 'string))) - (cons #'charToString (make-ast:type:function #f - (make-ast:type:primitive #f 'char) - (make-ast:type:primitive #f 'string))) - (cons #'stringToInt (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:primitive #f 'int))) - (cons #'stringToFloat (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:primitive #f 'float))) - (cons #'strlen (make-ast:type:function #f - (make-ast:type:primitive #f 'string) - (make-ast:type:primitive #f 'int))) - (cons #'substr (make-ast:type:function #f - (make-ast:type:tuple #f - (list (make-ast:type:primitive #f 'string) - (make-ast:type:primitive #f 'int) - (make-ast:type:primitive #f 'int))) - (make-ast:type:primitive #f 'string))) - (cons #'charAt (make-ast:type:function #f - (make-ast:type:tuple #f - (list (make-ast:type:primitive #f 'string) - (make-ast:type:primitive #f 'int))) - (make-ast:type:primitive #f 'char))) - (cons #'sqrt (make-ast:type:function #f - (make-ast:type:primitive #f 'float) - (make-ast:type:primitive #f 'float))) - )) - - (define tenv? bound-identifier-mapping?) - - (define printable-key syntax-e) - (define tenv-key=? bound-identifier=?) - (define (tenv-keystring (syntax-e k1)) - (symbol->string (syntax-e k2)))) - (define tenv-map bound-identifier-mapping-map) - (define tenv-for-each bound-identifier-mapping-for-each) - - (define (empty-tenv) (make-bound-identifier-mapping)) - (define (get-builtin-lenv) - (create-tenv (map car builtin-list) - (map (lambda (p) - (make-tenv:value (car p) (cdr p))) builtin-list))) - (define (extend-tenv key val) - (extend-tenv/checks key val (current-type-environment))) - (define (extend-lenv key val) - (extend-tenv/checks key val (current-lexical-environment))) - (define (extend-tenv-without-checking key val) - (extend-tenv/no-checks key val (current-type-environment))) - - (define (extend-tenv/checks key val tenv) - (if (bound-identifier-mapping-get tenv key (lambda () #f)) - (if (eqv? (string-ref (symbol->string (printable-key key)) 0) #\$) - (raise-read-error-with-stx - (format "~a already bound by a subclass or substruct" - (substring (symbol->string (printable-key key)) 1)) - key) - (raise-read-error-with-stx - (format "~a already bound by top-level definition" (printable-key key)) - key)) - (bound-identifier-mapping-put! tenv key val))) - (define (extend-tenv/no-checks key val tenv) - (bound-identifier-mapping-put! tenv key val)) - (define (create-tenv keys vals) - (let ((table (empty-tenv))) - (begin (for-each (lambda (k v) - (extend-tenv/checks k v table)) - keys vals) - table))) - - ;; only use this if you a) don't want an error or b) don't know what you should get. - (define (get-tenv-entry key) - (bound-identifier-mapping-get (current-type-environment) key (lambda () #f))) - (define (get-lenv-entry key) - (bound-identifier-mapping-get (current-lexical-environment) key (lambda () #f))) - - (define (get-type-entry type) - (if (ast:type:object:any? type) - (make-tenv:type #f (list) (list) (list)) - (let* ([name (ast:type:object:iface-name type)] - [entry (get-tenv-entry name)]) - (cond - [(not entry) - (raise-read-error-with-stx - (format "No type defined with name ~a" (printable-key name)) - name)] - [(not (tenv:type? entry)) - (raise-read-error-with-stx - (format "Definition of ~a is not a type" (printable-key name)) - name)] - [else entry])))) - - (define (get-class-entry name) - (let ([entry (get-tenv-entry name)]) - (cond - [(not entry) - (raise-read-error-with-stx - (format "No class defined with name ~a" (printable-key name)) - name)] - [(not (tenv:class? entry)) - (raise-read-error-with-stx - (format "Definition of ~a is not a class" (printable-key name)) - name)] - [else entry]))) - (define (get-mixin-entry name) - (let ([entry (get-tenv-entry name)]) - (cond - [(not entry) - (raise-read-error-with-stx - (format "No mixin defined with name ~a" (printable-key name)) - name)] - [(not (tenv:mixin? entry)) - (raise-read-error-with-stx - (format "Definition of ~a is not a mixin" (printable-key name)) - name)] - [else entry]))) - (define (get-member-type type name) - (let* ([entry (get-type-entry type)] - [mtype (find (lambda (m) - (tenv-key=? (tenv:member-name m) name)) - (append (tenv:type-members entry) - (tenv:type-inherited entry)))]) - (if mtype - (tenv:member-type mtype) - (raise-read-error-with-stx - (format "No member named ~a found for type ~a" - (printable-key name) - (if (ast:type:object:any? type) - 'Any - (printable-key (ast:type:object:iface-name type)))) - name)))) - (define (get-value-entry name) - (let ([entry (get-lenv-entry name)]) - (cond - [(not entry) - (raise-read-error-with-stx - (format "No function or top-level binding defined with name ~a" (printable-key name)) - name)] - [(not (tenv:value? entry)) - (raise-read-error-with-stx - (format "Definition of ~a is not a function definition or value binding" (printable-key name)) - name)] - [else entry]))) - - (define (fenv? v) (and (procedure? v) (procedure-arity-includes? v 1))) - (define (wrap-lenv) (wrap-as-function (current-lexical-environment))) - (define (wrap-as-function tenv) - (lambda (name) - (let ([entry (bound-identifier-mapping-get tenv name (lambda () #f))]) - (if entry (tenv:value-type entry) #f)))) - - (define (extend-fenv key value fenv) - (lambda (name) - (if (tenv-key=? key name) - value - (fenv name)))) - - (define (extend-fenv-ast:formal formal fenv) - (extend-fenv (ast:formal-name formal) (ast:formal-type formal) fenv)) - - (define empty-fenv (lambda (name) #f)) - - (provide (struct tenv:entry (stx)) - (struct tenv:init (name type optional?)) - (struct tenv:member (stx name type)) - (struct tenv:type (supers members inherited)) - (struct tenv:class (sub-type impls inits final? super)) - (struct tenv:mixin (arg-type sub-type impls inits - withs final?)) - (struct tenv:value (type))) - (provide/contract [tenv? (any/c . -> . boolean?)] - [printable-key (identifier? . -> . symbol?)] - [tenv-key=? (identifier? identifier? . -> . any)] - [tenv-key . any)] - [tenv-map (tenv? - (identifier? tenv:entry? . -> . any) - . -> . - list?)] - [tenv-for-each (tenv? - (identifier? tenv:entry? . -> . void?) - . -> . - void?)] - [empty-tenv (-> tenv?)] - [get-builtin-lenv (-> tenv?)] - [extend-tenv (identifier? tenv:entry? . -> . void?)] - [extend-lenv (identifier? tenv:value? . -> . void?)] - [extend-tenv-without-checking (identifier? tenv:entry? . -> . void?)] - [get-tenv-entry (identifier? . -> . (union tenv:entry? false/c))] - [get-lenv-entry (identifier? . -> . (union tenv:entry? false/c))] - [get-type-entry ((union ast:type:object:iface? - ast:type:object:any?) . -> . tenv:type?)] - [get-class-entry (identifier? . -> . tenv:class?)] - [get-mixin-entry (identifier? . -> . tenv:mixin?)] - [get-member-type ((union ast:type:object:iface? - ast:type:object:any?) - identifier? . -> . ast:type?)] - [get-value-entry (identifier? . -> . tenv:value?)] - [fenv? (any/c . -> . boolean?)] - [wrap-lenv (-> fenv?)] - [empty-fenv fenv?] - [extend-fenv (identifier? ast:type? fenv? . -> . fenv?)] - [extend-fenv-ast:formal (ast:formal? fenv? . -> . fenv?)] - ) - - ) diff --git a/collects/honu/test-cases.ss b/collects/honu/test-cases.ss deleted file mode 100644 index 29805bae5f..0000000000 --- a/collects/honu/test-cases.ss +++ /dev/null @@ -1,64 +0,0 @@ -(module test-cases mzscheme - - (require (lib "contract.ss") - (prefix srfi13: (lib "13.ss" "srfi")) - "private/tools/test.ss" - "private/typechecker/typecheck-expression.ss" - "tenv.ss" - "ast.ss" - "top.ss") - - (define example-files - (list "examples/BoundedStack.honu" - "examples/EvenOddClass.honu" - "examples/List.honu" - "examples/Y.honu" - "examples/bind-tup-top.honu" - "examples/cond-test.honu" - "examples/even-odd.honu" - "examples/exprs.honu" - "examples/point.honu" - "examples/struct.honu" - "examples/tup-bind.honu" -; "examples/types-error.honu" - "examples/types.honu" -; "examples/nonexistent.honu" - )) - - (provide void-example example-files) - - (define (void-example) - (typecheck-expression - (wrap-lenv) #f - (make-ast:expr:sequence - #'() - (list (make-ast:expr:literal #'() (make-ast:type:primitive #'() 'int) #'5)) - (make-ast:expr:literal #'() (make-ast:type:primitive #'() 'int) #'4)))) - - (define-test-suite honu-tests - (test-case - examples-simple - (map test-file example-files) - [pred: (lambda (all-results) - (andmap (lambda (file-results) - (andmap (lambda (result) (eq? result #t)) - file-results)) - all-results))]) - (test-suite typechecker - (test-suite expression - (test-case sequence-not-void - (void-example) - [error: (lambda (exn) (srfi13:string-contains (exn-message exn) "void"))])))) - - (provide/contract - [run-tests (-> report?)] - [run-examples (-> void?)] - ) - - (define (run-tests) - (honu-tests)) - - (define (run-examples) - (for-each run-program example-files)) - - ) \ No newline at end of file diff --git a/collects/honu/test-tools.ss b/collects/honu/test-tools.ss deleted file mode 100644 index 44a1dec2e1..0000000000 --- a/collects/honu/test-tools.ss +++ /dev/null @@ -1,10 +0,0 @@ -(module test-tools mzscheme - - (require (lib "class.ss")) - - (provide (all-from (lib "class.ss")) - mixin?) - - (define mixin? null?) - - ) diff --git a/collects/honu/tool.ss b/collects/honu/tool.ss deleted file mode 100644 index e2e91b03b0..0000000000 --- a/collects/honu/tool.ss +++ /dev/null @@ -1,361 +0,0 @@ -(module tool mzscheme - (require (lib "tool.ss" "drscheme") - (lib "mred.ss" "mred") - (lib "framework.ss" "framework") - (lib "unitsig.ss") - (lib "etc.ss") - (lib "class.ss") - (lib "list.ss" "srfi" "1") - (lib "match.ss") - (lib "port.ss") - "parsers/lex.ss" - "parsers/parse.ss" - "private/typechecker/type-utils.ss" - (only "base.ss" null%) - "tenv.ss" - "compile.ss" - "format.ss" - (lib "string-constant.ss" "string-constants")) - - (provide tool@) - - ;; tool@ : Unit/Sig[drscheme:tool^ -> drscheme:tool-exports^] - ;; Implements Honu as a DrScheme language - (define tool@ - (unit/sig drscheme:tool-exports^ - (import drscheme:tool^) - - ;; phase1 : -> Void - ;; Performs general language extensions to DrScheme for Honu. - ;; Currently none exist. - (define (phase1) (void)) - - ;; phase2 : -> Void - ;; Adds the Honu language to DrScheme. - (define (phase2) - (define honu (new ((drscheme:language:get-default-mixin) honu-lang%))) - (drscheme:language-configuration:add-language honu) - (send honu pre-initialize)) - - ;; honu-lang% : Class[drscheme:language:language<%>] - ;; Honu implementation as a class. - (define honu-lang% - (class* object% (drscheme:language:language<%>) - - ;; tenv : TypeEnvironment - ;; The current type environment for evaluation. - (define tenv #f) - - ;; lenv : LexicalEnvironment - ;; The current lexical environment for evaluation. - (define lenv #f) - - ;; pre-initialize : -> Void - ;; Hooks Honu up to DrScheme after being added as a language. - (define/public (pre-initialize) - (drscheme:modes:add-mode "Honu mode" mode-surrogate repl-submit matches-language) - (color-prefs:add-to-preferences-panel "Honu" extend-preferences-panel) - (for-each register-color-pref color-prefs-table)) - - ;; first-opened : -> Void - ;; Sets Honu state to initial values. - (define/public (first-opened) - (reset-evaluation!)) - - ;; get-comment-character : -> String Character - ;; Provides prefix and filler character for comments - ;; for use in "Insert Large Letters" - (define/public (get-comment-character) (values "//" #\*)) - - ;; default-settings : -> HonuSetting - ;; Provides default global Honu configuration - (define/public (default-settings) #f) - - ;; default-settings? : HonuSetting -> Boolean - ;; Reports whether Honu configuration is set to defaults - (define/public (default-settings? s) #t) - - ;; marshall-settings : HonuSetting -> Writable - ;; Converts a Honu configuration to a value which can be - ;; written to a port. - (define/public (marshall-settings s) s) - - ;; unmarshall-settings : Writable -> HonuSetting - ;; Converts the result of a previous marshall-settings to - ;; a Honu configuration. - (define/public (unmarshall-settings s) s) - - ;; config-panel : panel% -> [Case (-> HonuSetting) (HonuSetting -> Void)] - ;; Assembles a language configuration dialog for Honu - ;; and produces a get/set function for the displayed configuration. - (define/public (config-panel parent) - (letrec ([output-panel (new group-box-panel% - [label "Honu Preferences (Currently Empty)"] - [parent parent] - [alignment '(left center)])]) - (case-lambda - [() (default-settings)] - [(settings) (void)]))) - - ;; front-end/complete-program : - ;; InputPort HonuSetting TeachpackCache -> (-> (Union Syntax EOF)) - ;; Produces a thunk which compiles and returns a Honu definition when one - ;; is available on the input port, or EOF when none are left. - (define/public (front-end/complete-program original-port settings teachpack-cache) - (define port (single-stream-port original-port)) - (reset-evaluation!) - (lambda () - (if (eof-object? (peek-char-or-special port)) - eof - (let*-values - ([(syntax-annotation compiled-defns) - (compile/defns tenv lenv (parse-port port (object-name port)))]) - ;; This particular syntax construction is compatible with Check Syntax - ;; and can be distinguished from compiled Interactions. - (datum->syntax-object - #f - (list 'begin - syntax-annotation - (datum->syntax-object - #f - (cons 'begin compiled-defns) - #f)) - #f))))) - - ;; front-end/interaction : - ;; InputPort HonuSetting TeachpackCache -> (-> (Union Syntax EOF)) - ;; Produces a thunk which compiles and returns a Honu expression or definition - ;; when one is available on the input port, or EOF when none are left. - (define/public (front-end/interaction original-port settings teachpack-cache) - (define port (single-stream-port original-port)) - (lambda () - (if (eof-object? (peek-char-or-special port)) - eof - (let*-values ([(compiled-expr type) - (compile/interaction - tenv lenv - (parse-interaction port (object-name port)))]) - (datum->syntax-object - #f - (if type - `(compiled-expression ,compiled-expr ,type) - `(compiled-binding ,compiled-expr)) - #f))))) - - ;; get-style-delta : -> #f - ;; Reports that the name Honu has no specific text style. - (define/public (get-style-delta) #f) - - ;; order-manuals : [Listof ByteString] -> (values [Listof ByteString] Boolean) - ;; Reports which manuals from the input contain Honu documentation - ;; and whether to search doc.txt files for Honu documentation. - ;; Currently lists no manuals, but includes doc.txt. - (define/public (order-manuals manuals) - (values '() #t)) - - ;; get-language-name : -> String - ;; Produces Honu's name. - (define/public (get-language-name) "Honu") - - ;; get-language-url : -> (Union String #f) - ;; Reports that Honu has no URL. - (define/public (get-language-url) #f) - - ;; get-language-position : -> [NonEmptyListof String] - ;; Reports Honu's place in the language hierarchy. - (define/public (get-language-position) - (list (string-constant experimental-languages) - "Honu")) - - ;; get-language-numbers : -> [NonEmptyListof String] - ;; Reports Honu's sort order in the language hierarchy. - (define/public (get-language-numbers) (list 1000 10)) - - ;; get-one-line-summary : -> String - ;; Produces a short description of Honu. - (define/public (get-one-line-summary) "Honu (not a Scheme dialect)") - - ;; on-execute : HonuSetting ((-> Void) -> Void) -> Void - ;; Sets parameters for Honu execution. - (define/public (on-execute settings run-in-user-thread) - (dynamic-require '(lib "base.ss" "honu") #f) - (let ([path ((current-module-name-resolver) '(lib "base.ss" "honu") #f #f)] - [namespace (current-namespace)]) - (run-in-user-thread - (lambda () - (define base-eval (drscheme:debug:make-debug-eval-handler (current-eval))) - (define (eval stx) - (syntax-case stx (compiled-binding compiled-expression) - [(compiled-binding BINDING) - (base-eval (namespace-syntax-introduce #'BINDING))] - [(compiled-expression EXPR TYPE) - (cons (base-eval (namespace-syntax-introduce #'EXPR)) - (syntax-e #'TYPE))] - [(_ ANNOTATION PROGRAM) - (base-eval (namespace-syntax-introduce #'PROGRAM))])) - - (current-eval eval) - (error-display-handler - (drscheme:debug:make-debug-error-display-handler (error-display-handler))) - (namespace-attach-module namespace path) - (namespace-require path))))) - - ;; render-value : Value HonuSetting OutputPort -> Void - ;; Writes value to port as a single line with no newline. - (define/public (render-value value settings port) - (display (format-honu value settings) port)) - - ;; render-value/format : Value HonuSetting OutputPort (Union Integer #f) -> Void - ;; Writes value to port as lines of length no greater than width. - ;; Terminates all lines with newline. - ;; Currently fails to actually account for width. - (define/public (render-value/format value settings port width) - (render-value value settings port) - (newline port)) - - ;; create-executable : HonuSetting (Union Dialog Frame) String TeachpackCache -> Void - ;; Raises an error reporting that Honu programs cannot be made into executables. - (define/public (create-executable settings parent src-file teachpacks) - (message-box "Unsupported" - "Sorry - executables are not supported for Honu at this time" - parent)) - - ;; Finish the class instantiation - (super-new) - - ;; ------------------------------------------------------------ - ;; BEGIN PRIVATE FUNCTIONS - - ;; reset-evaluation! : -> Void - ;; Restore Honu state to initial values. - (define (reset-evaluation!) - (set! tenv (empty-tenv)) - (set! lenv (get-builtin-lenv))) - - ;; format-honu : (cons Value Ast:Type) HonuSetting -> String - ;; Formats the result of Honu evaluation for printing. - (define (format-honu result settings) - (format "~a : ~a" - (honu-value->string (car result)) - (honu-type->string (cdr result)))) - - ;; matches-language : [NonEmptyListof String] -> Boolean - ;; Reports whether a language dialog choice matches Honu. - (define (matches-language l) - (equal? l (get-language-position))) - - ;; register-color-pref : (list Symbol Color String) -> Void - ;; Registers a single color preference setting in the correct menu. - (define (register-color-pref pref) - (let ([sym (car pref)] - [color (cadr pref)]) - (color-prefs:register-color-pref (short-sym->pref-name sym) - (short-sym->style-name sym) - color))) - - ;; color-prefs-table : [Listof (list Symbol Color String)] - ;; Lists the Honu color preference entries - (define color-prefs-table - `((keyword ,(make-object color% "black") "keyword") - (parenthesis ,(make-object color% 132 60 36) "parenthesis") - (string ,(make-object color% "forestgreen") "string") - (literal ,(make-object color% "forestgreen") "literal") - (comment ,(make-object color% 194 116 31) "comment") - (error ,(make-object color% "red") "error") - (identifier ,(make-object color% 38 38 128) "identifer") - (default ,(make-object color% "black") "default"))) - - ;; short-sym->pref-name : symbol -> symbol - ;; returns the preference name for the color prefs - (define (short-sym->pref-name sym) (string->symbol (short-sym->style-name sym))) - - ;; short-sym->style-name : symbol->string - ;; converts the short name (from the table above) into a name in the editor list - ;; (they are added in by `color-prefs:register-color-pref', called below) - (define (short-sym->style-name sym) (format "honu:syntax-coloring:scheme:~a" sym)) - - ;; extend-preferences-panel : vertical-panel -> void - ;; adds in the configuration for the Honu colors to the prefs panel - (define (extend-preferences-panel parent) - (for-each - (lambda (line) - (let ([sym (car line)]) - (color-prefs:build-color-selection-panel - parent - (short-sym->pref-name sym) - (short-sym->style-name sym) - (format "~a" sym)))) - color-prefs-table)) - - ;; mode-surrogate : TextMode - ;; Create the Honu editing mode - (define mode-surrogate - (new color:text-mode% - (matches (list (list '|{| '|}|) - (list '|(| '|)|) - (list '|[| '|]|))) - (get-token get-syntax-token) - (token-sym->style short-sym->style-name))) - - ;; repl-submit: text int -> bool - ;; Determines if the reple should submit or not - (define (repl-submit text prompt-position) - (let ((is-empty? #t) - (is-string? #f) - (open-parens 0) - (open-braces 0) - (open-curlies 0)) - (let loop ((index 1) (char (send text get-character prompt-position))) - (unless (eq? char #\nul) - (cond - ((eq? char #\() - (set! is-empty? #f) - (unless is-string? (set! open-parens (add1 open-parens))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((eq? char #\)) - (set! is-empty? #f) - (unless is-string? (set! open-parens (sub1 open-parens))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((eq? char #\{) - (set! is-empty? #f) - (unless is-string? (set! open-curlies (add1 open-curlies))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((eq? char #\}) - (set! is-empty? #f) - (unless is-string? (set! open-curlies (sub1 open-curlies))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((eq? char #\[) - (set! is-empty? #f) - (unless is-string? (set! open-braces (add1 open-braces))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((eq? char #\]) - (set! is-empty? #f) - (unless is-string? (set! open-braces (sub1 open-braces))) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ;; beginning of string - ((eq? char #\") - (set! is-empty? #f) - (set! is-string? (not is-string?)) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - ((char-whitespace? char) - (loop (add1 index) (send text get-character (+ index prompt-position)))) - (else - (set! is-empty? #f) - (loop (add1 index) (send text get-character (+ index prompt-position))))))) - (not (or (not (= open-parens 0)) - (not (= open-braces 0)) - (not (= open-curlies 0)) - is-empty?)))) - - ;; single-stream-port : InputPort -> InputPort - ;; Consumes an arbitrary input port. - ;; Produces a port which produces the same data as its input - ;; up to EOF, then produces EOF constantly. - (define (single-stream-port port) - (let*-values ([(in-port out-port) - (make-pipe #f (object-name port) (object-name port))]) - (copy-port port out-port) - (close-output-port out-port) - in-port)) - - ))))) diff --git a/collects/honu/top.ss b/collects/honu/top.ss deleted file mode 100644 index aa95b72e8d..0000000000 --- a/collects/honu/top.ss +++ /dev/null @@ -1,144 +0,0 @@ -(module top mzscheme - - (require (lib "etc.ss") - (lib "class.ss") - (lib "contract.ss") - (lib "boundmap.ss" "syntax") - "parsers/parse.ss" - "parsers/post-parsing.ss" - "private/typechecker/type-utils.ss" - "private/typechecker/typechecker.ss" - "private/compiler/translate.ss" - "private/compiler/translate-utils.ss" - "tenv-utils.ss" - "parameters.ss" - "honu-context.ss" - "ast.ss" - "tenv.ss" - "private/tools/general.ss" - ) - - (provide/contract - [current-tenv parameter?] - [current-lenv parameter?] - ) - - (define current-tenv (make-parameter (empty-tenv))) - (define current-lenv (make-parameter (get-builtin-lenv))) - - (provide/contract - [reset-env (-> void?)] - ) - - (define (reset-env) - (current-tenv (empty-tenv)) - (current-lenv (get-builtin-lenv))) - - (define-syntax (with-env stx) - (syntax-case stx () - [(_ BODY ...) - #`(parameterize ([current-type-environment (current-tenv)] - [current-lexical-environment (current-lenv)]) - BODY ...)])) - - (define-syntax (with-context stx) - (syntax-case stx () - [(_ BODY ...) - #`(parameterize ([current-compile-context honu-compile-context]) - BODY ...)])) - - (provide/contract - [ast-from-file (path-string? . -> . (listof ast:defn?))] - [check-defns ((listof ast:defn?) . -> . (listof ast:defn?))] - [translate-defns ((listof ast:defn?) . -> . (syntax/c any/c))] - ) - - (define (ast-from-file file) - (with-env - (post-parse-program - (add-defns-to-tenv - (parse-port (open-input-file file) file))))) - - (define (check-defns defns) - (with-env (typecheck defns))) - - (define (translate-defns defns) - (with-env - (with-context - (let-values - ([(annotations syntax) (translate defns)]) - (namespace-syntax-introduce (datum->syntax-object #f (cons 'begin syntax) #f)))))) - - (define (lenv-names) - (let* ([lenv (current-lenv)] - [orig (get-builtin-lenv)] - [ids '()]) - (bound-identifier-mapping-for-each - lenv - (lambda (id entry) - (if (bound-identifier-mapping-get orig id (lambda () #f)) - (void) - (set! ids (cons (syntax-e id) ids))))) - (reverse! ids))) - - (define (tenv:entry-mangled-name id entry) - (cond [(tenv:type? entry) (syntax-e (translate-iface-name (make-iface-type id id)))] - [(tenv:class? entry) (syntax-e (translate-class-name id))] - [(tenv:mixin? entry) (syntax-e (translate-mixin-name id))])) - - (define (tenv-names) - (let* ([tenv (current-tenv)]) - (bound-identifier-mapping-map tenv tenv:entry-mangled-name))) - - (provide/contract - [eval-after-program (path-string? syntax? . -> . any)] - [run-program (path-string? . -> . (values (listof symbol?) (listof symbol?)))] - [run-programs ((listof path-string?) . -> . - (values (listof (listof symbol?)) (listof (listof symbol?))))] - ) - - (define (eval-after-program file stx) - (reset-env) - (let* ([ast (ast-from-file file)] - [ast (check-defns ast)] - [defs (translate-defns ast)]) - (eval - #`(begin #,defs #,stx)))) - - (define (run-program file) - (reset-env) - (eval-syntax (translate-defns (check-defns (ast-from-file file)))) - (values (tenv-names) (lenv-names))) - - (define (run-programs files) - (map-values run-program files)) - - (define (program-syntax file) - (let* ([port (open-input-file file)]) - #`(begin - #,@(let read-loop - ([sexps (list)] - [input (read-syntax file port)]) - (if (eof-object? input) - (reverse sexps) - (read-loop (cons input sexps) (read-syntax file port))))))) - - (provide/contract - [test-file (path-string? . -> . any)] - ) - - (define (test-file file) - (let* ([honu-path (if (path? file) file (string->path file))] - [test-path (path-replace-suffix honu-path "-test.ss")]) - (unless (file-exists? honu-path) - (error 'test-file "~s not found" (path->string honu-path))) - (unless (file-exists? test-path) - (error 'test-file "~s not found" (path->string test-path))) - (let* ([stx (program-syntax test-path)]) - (eval-after-program - honu-path - #`(begin - (require (lib "test-tools.ss" "honu")) - #,stx))))) - - )