Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
acaceae
WIP implement runtime support for polymorphism
Technius Dec 12, 2019
74e8ccc
Fix test suite linker flags
Technius Dec 15, 2019
d7afb51
WIP More work on boxed/tagged data compilation
Technius Dec 15, 2019
b7eaec1
WIP track boxing in AST to JoinIR conversion
Technius Dec 16, 2019
438ead7
Finish codegen for tag/untagging
Technius Dec 17, 2019
94e837e
Add boxing logic to more expression types
Technius Dec 17, 2019
6525b25
Fix redundant type tags getting created
Technius Dec 17, 2019
26df57f
Box arguments to if and case
Technius Dec 17, 2019
64e7f59
Handle (un)boxing correctly for unboxed types during codegen
Technius Dec 18, 2019
8f79e0f
Instantiate type variables for case/ctor in type checker
Technius Dec 19, 2019
57294bc
Rewrite boxing logic to use continuation passing style
Technius Dec 19, 2019
0ed77b2
Fixing scoping errors in typecheck and codegen
Technius Dec 19, 2019
829da43
Fix JoinIR+codegen for case on polymorphic ADTs; fix scoping issue
Technius Dec 19, 2019
22a8be6
Update parser to handle polymorphic ADTs
Technius Dec 19, 2019
62484bf
Fix printing of ADT type arguments
Technius Dec 19, 2019
2be7302
Fix type check regression: function arg count not checked properly
Technius Dec 20, 2019
e53d8e8
Fix type variables not parsing correctly in function signatures
Technius Dec 20, 2019
84bc5b0
Fix function ref lookups in AST to JoinIR transformation
Technius Dec 20, 2019
3f8c1b6
Fix AST to Join IR transformation of case branch bindings
Technius Dec 20, 2019
0c37cd0
Fix constructor memory allocation
Technius Dec 20, 2019
01a7da4
Update polymorphism test cases
Technius Dec 20, 2019
5b93c6e
Fix boxing of doubles
Technius Dec 30, 2019
4815877
Fix substitution of ADT type variables in type checker
Technius Dec 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions runtime/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,23 @@ int simpl_string_print(const struct simpl_string* s) {
free(cstring);
return 0;
}

uint32_t simpl_tagged_size(const struct simpl_type_tag* const tag) {
return tag->size;
}

const struct simpl_type_tag* const simpl_tagged_tag(struct simpl_tagged_value* value) {
return value->type_tag;
}

void* simpl_tagged_unbox(struct simpl_tagged_value* value) {
return value->data;
}


struct simpl_tagged_value* simpl_tagged_box(struct simpl_type_tag* tag, void* data) {
struct simpl_tagged_value *value = simpl_malloc(sizeof(struct simpl_tagged_value));
value->type_tag = tag;
value->data = data;
return value;
}
41 changes: 41 additions & 0 deletions runtime/runtime.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdint.h>

#ifndef RUNTIME_H
#define RUNTIME_H
Expand Down Expand Up @@ -38,4 +39,44 @@ char* simpl_string_cstring(const struct simpl_string* s);

int simpl_string_print(const struct simpl_string* s);

/**
* Describes static information about a type. This struct should not be visible
* from SimPL programs.
*/
struct simpl_type_tag {
/**
* The size (e.g. when compiled) of the type, in bytes.
*/
uint32_t size;
};

/**
* Returns the size recorded in the type tag.
*/
uint32_t simpl_tag_size(const struct simpl_type_tag* const);

/**
* A value tagged with its type tag. Used for polymorphic functions and
* variables.
*/
struct simpl_tagged_value {
const struct simpl_type_tag* type_tag;
void* data;
};

/**
* Returns the type tag of a tagged value.
*/
const struct simpl_type_tag* const simpl_tagged_tag(struct simpl_tagged_value*);

/**
* Returns a pointer to the boxed value of a tagged value.
*/
void* simpl_tagged_unbox(struct simpl_tagged_value*);

/**
* Boxes the given value
*/
struct simpl_tagged_value* simpl_tagged_box(struct simpl_type_tag* tag, void* data);

#endif
154 changes: 79 additions & 75 deletions sample.spl
Original file line number Diff line number Diff line change
Expand Up @@ -5,78 +5,82 @@ data MaybeI = { JustI Double | Nothing }
# data Barbar a = { Asdf Int a }

# fun id (x : a) : a := { x }

fun not (b : Bool) : Bool := { if b then false else true }

fun and (p : Bool, q : Bool) : Bool := { if p then (if q then true else false) else false }

fun or (p : Bool, q : Bool) : Bool := { if p then true else (if q then true else false) }

fun factorial (x : Int) : Int := {
if (x <= 0) then 1
else x * @factorial(x - 1)
}

fun even (x: Int) : Bool := {
if (x <= 0) then true
else @not(@odd(x - 2))
}

fun odd (x: Int) : Bool := {
if (x <= 1) then true
else @not(@even(x - 2))
}

fun nested_ifs : Double := {
(if true then (if true then 4.0 else 5.0) else (if false then 2.0 else 3.0) + 1.0) * 2.0
}

fun main : Int := {
case JustI 10.0 of
JustI x =>
let msg = println("In Just branch") in
let mynum = @abs(-1) in
(if (@even(4)) then @double_me(5) else @factorial(6)) * @asdf * mynum
Nothing =>
let msg = println("In Nothing branch") in
let res = 4 in
@double_me(res + 1)
}

fun asdf : Int := {
(if false then 5 else 10) + 2
}

fun double_me (x : Int) : Int := { x * 2 }

fun foo : Foo := {
Bar 5.0
}

fun foo2 : Bool := {
case Bar 5.0 of
Bar x => true
}

fun lots_of_lets : Double := {
let x = if true then 1.0 else 2.0 in
let y = if true then x * 2.0 else x * 2.0 + 1.0 in
y
}

fun fun_ptr : Int -> Int := { &double_me }

fun fun_ptr_test (b : Bool) : Int := {
let f = if b then &double_me else &factorial in
@f(4)
}

fun cast_test_1 : Int := {
(1 + 1) * (cast 2.0 as Int)
}

fun cast_test_2 : Int := {
(1 * 1) + (cast 2.0 as Int)
}

fun abs (x : Int) : Int := extern
#
# fun eqargs (x : a, y : a, z: b) : a := { x }

fun main : Int := { let x = &asdf in 5 }

# fun not (b : Bool) : Bool := { if b then false else true }
#
# fun and (p : Bool, q : Bool) : Bool := { if p then (if q then true else false) else false }
#
# fun or (p : Bool, q : Bool) : Bool := { if p then true else (if q then true else false) }
#
# fun factorial (x : Int) : Int := {
# if (x <= 0) then 1
# else x * @factorial(x - 1)
# }
#
# fun even (x: Int) : Bool := {
# if (x <= 0) then true
# else @not(@odd(x - 2))
# }
#
# fun odd (x: Int) : Bool := {
# if (x <= 1) then true
# else @not(@even(x - 2))
# }
#
# fun nested_ifs : Double := {
# (if true then (if true then 4.0 else 5.0) else (if false then 2.0 else 3.0) + 1.0) * 2.0
# }
#
# fun main : Int := {
# case JustI 10.0 of
# JustI x =>
# let msg = println("In Just branch") in
# let mynum = @abs(-1) in
# (if (@even(4)) then @double_me(5) else @factorial(6)) * @asdf * mynum
# Nothing =>
# let msg = println("In Nothing branch") in
# let res = 4 in
# @double_me(res + 1)
# }
#
# fun asdf : Int := {
# (if false then 5 else 10) + 2
# }
#
# fun double_me (x : Int) : Int := { x * 2 }
#
# fun foo : Foo := {
# Bar 5.0
# }
#
# fun foo2 : Bool := {
# case Bar 5.0 of
# Bar x => true
# }
#
# fun lots_of_lets : Double := {
# let x = if true then 1.0 else 2.0 in
# let y = if true then x * 2.0 else x * 2.0 + 1.0 in
# y
# }
#
# fun fun_ptr : Int -> Int := { &double_me }
#
# fun fun_ptr_test (b : Bool) : Int := {
# let f = if b then &double_me else &factorial in
# @f(4)
# }
#
# fun cast_test_1 : Int := {
# (1 + 1) * (cast 2.0 as Int)
# }
#
# fun cast_test_2 : Int := {
# (1 * 1) + (cast 2.0 as Int)
# }
#
# fun abs (x : Int) : Int := extern
Loading