diff options
-rw-r--r-- | llvm.cpp | 5 | ||||
-rwxr-xr-x | test.sh | 19 | ||||
-rw-r--r-- | test/def.tpr | 8 | ||||
-rw-r--r-- | test/intro.tpr | 148 | ||||
-rw-r--r-- | test/nest.tpr | 6 | ||||
-rw-r--r-- | test/poly.tpr | 6 |
6 files changed, 190 insertions, 2 deletions
@@ -166,8 +166,9 @@ compileFunction(CEnv& cenv, const std::string& name, const Type* retT, const ATu Function* f = Function::Create(fT, linkage, name, llengine(cenv)->module); if (f->getName() != name) { - f->eraseFromParent(); - throw Error(loc, (format("function `%1%' redefined") % name).str()); + cenv.out << "DIFFERENT NAME: " << f->getName() << endl; + /*f->eraseFromParent(); + throw Error(loc, (format("function `%1%' redefined") % name).str());*/ } // Set argument names in generated code @@ -0,0 +1,19 @@ +#!/bin/sh + +run() { + prog=$1 + desired=$2 + out=`./build/tuplr $prog` + if [ "$out" != "$desired" ]; then + echo "FAIL: $prog"; + echo " Expected: \"$desired\""; + echo " Output: \"$out\""; + else + echo "PASS: $prog" + fi +} + +run './test/ack.tpr' '8189 : Int' +run './test/def.tpr' '3 : Int' +run './test/fac.tpr' '720 : Int' +run './test/nest.tpr' '6 : Int' diff --git a/test/def.tpr b/test/def.tpr new file mode 100644 index 0000000..dd9a0c8 --- /dev/null +++ b/test/def.tpr @@ -0,0 +1,8 @@ +(def foo + (fn (x) + (def y 2) + (def z 3) + z)) + +(foo 3) + diff --git a/test/intro.tpr b/test/intro.tpr new file mode 100644 index 0000000..73a21bb --- /dev/null +++ b/test/intro.tpr @@ -0,0 +1,148 @@ +;;; NOTE: This document is just a draft idea sketch pad + +;;; Data types + +; Tuplr uses algebraic datatypes which can also be used in an +; object based style with more flexibility than typical of +; languages with algebraic datatypes +; +; There is a single way of defining a type (the 'type' form) which +; encompasses unions, records, objects, etc. + +; A type is a discriminated union ("or") of types. +; Type names (including variables) always start with an uppercase letter. + +; There are many equivalent terms for kinds of types. We uniformly use: +; "Union" : "and", sum type +; "Record" : "or", product type, object, struct + +; Example: A Tree is a Node with a value and left/right children, or Nothing +; "Nothing" and "Node" are called constructors. In this case both are Records +(type (Tree T) + (Nothing) + (Node value :T + left :(Tree T) + right :(Tree T))) + +; Constructors have one of two forms: +; Union constructors have parameters enclosed in parenthesis, e.g. +; (Maybe (Nothing) (Just x)) +; Record constructors do not, e.g. +; (Point x y) +; +; Thus, types can be arbitrarily combined/nested, e.g +(type (Collection T) + (Tree + (Nothing) + (Node value :T + left :(Tree T) + right :(Tree T))) + (List + (Nothing) + (Node value :T + next :(List T)))) + +; Tree height (functional pattern matching style) +(def (height t) + (match t:Tree + (Empty) 0 + (Node v l r) (+ 1 (max (height l) (height r))))) + +; equivalently +(def (height t) + (match t + (Tree.Empty) 0 + (Tree.Node v l r) (+ 1 (max (height l) (height r))))) + +; GADTs +; The return type of a constructor can be specified explicitly +; e.g. a well-typed evaluator (this is not possible without GADTs): +; (http://www.haskell.org/ghc/docs/latest/html/users_guide/data-type-extensions.html#gadt) +(type (Term T) + (Lit i :Int) :(Term Int) + (Succ t :Int) :(Term Int) + (IsZero t :Int) :(Term Bool) + (If c :Bool + t :(Term T) + e :(Term T)) :(Term T) + (Pair a :(Term T) + b :(Term T)) :(Term T)) + +; Objects +; A type with a single product constructor is simply that product type +; (i.e. sum types with a single element do not exist by definition) +; This can be used to create "record" or "object" types without any special +; language facilities: +(type (Person) + (Person + name :String + age :Number)) + +; The '.' ("dot") operator can be used to inspect product types + +(def dave (Person 'name "Dave" 'age 27)) + +(. dave name) ; => "Dave" +(. dave age) ; => 27 + + +;; Everything Is A ... + +; Everything in Tuplr is a closure. Records are simply closures with some +; internal definitions exposed (much like modules). + +; Objects can be created with their constructors: +(def steve (Person "Steve" 24)) + +; Equivalently (aside from type) with the generic Object constructor: +(def steve2 (Object 'name "Steve" 'age 24)) + +; Equivalently (aside from type) manually: +(def steve2 + (fn () + (def name "Steve") + (def age 24) + (export name age))) + +;; RDF style objects + +; A class is just an object (closure) with some required properties (ala OWL) +; All object fields have a URI. If a prefix is not explicitly given, the URI +; is the base URI of the document, followed by the Class, a dot, then the name. +; e.g. if the base URI of this document is "foo://bar/" the URI of "age" below is: +; foo://bar/Person.age + +(ns foaf "http://xmlns.com/foaf/0.1/") +(ns geom "http://www.charlestoncore.org/ontology/2005/08/geometry") + +(def (Point T) + (Point + geom.x :T + geom.y :T)) + +(type (Person) + foaf.name :String + age :Number) + +(type (Cat) + foaf.name :String + age :Number) + +; A 'constructor' (nothing special, just a function that returns a closure) +(def (newborn name) + (fn () + (def type Person) ; special, compiler will check required properties exist + (def foaf.name name) + (def age 1))) + +; Equivalently, +(def (newborn name) + (Person + foaf.name name + age 1)) + +(def stewie (newborn "Stewie")) +(def stewies-age (. stewie age)) + + + diff --git a/test/nest.tpr b/test/nest.tpr new file mode 100644 index 0000000..3085737 --- /dev/null +++ b/test/nest.tpr @@ -0,0 +1,6 @@ +(def (f x) + (def (g y) + (* y 2)) + (g x)) + +(f 3) diff --git a/test/poly.tpr b/test/poly.tpr new file mode 100644 index 0000000..33922e3 --- /dev/null +++ b/test/poly.tpr @@ -0,0 +1,6 @@ +(def eq (fn (x y) (= x y))) + +(eq 1 2) +(eq 1 1) +(eq 10.0 20.0) +(eq 10.0 10.0) |