Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty return #12

Merged
merged 3 commits into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 12 additions & 18 deletions examples/test.vlp
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
# a jungle of random tests
f = (x, [y, z]) => [&x..10, y..z]
a = f(0, [0, 10])
[b, c] = a

# functions
# :> f

# testing compound assignment operators
a = 3
a += 2
a /= 5
# tuples
# :> [1 > 0, [1, 0.0], f, b, c]

b = 2.5
b *= 4.0
b -= a.5 # conversion
# iterators
# :> c :: i => [i, i.0, f, f(i-5, [0, 2])]

f = () => ~b # conversion

c = [1.0, 2, [3.0, 4]] # tuples

[d, _, e] = c # tuple decomposition

g = (-2)..2 # ranges

# printing various types, float precision
:> [b, 1 > 0, !(5 == ~5.0), [1.0, 2, [3.0, 4]], 1.0 / 3.0, f(), f, [f], g[1]]
# lists
:> b
2 changes: 2 additions & 0 deletions volpe/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ def number_iter(self, tree: TypeTree):
start = read_environment(b, args[0], env_types)[0]
b.ret(b.add(start, args[1]))

# TODO going in reverse
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this about?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0..10 gives

i => {i >= 0; i < 10; :> i}

I want 10..0 to give

i => {i >= 0; i < 10; :> 9 - i} 
# 9 and not 10, because I want 10..0 to be reverse of 0..10

This is not related to the pretty return, so I can remove it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah makes sense


env_ptr = write_environment(self.builder, [values[0]])
list_value = tree.return_type(ir.Undefined)
list_value = self.builder.insert_value(list_value, self.builder.insert_value(closure, env_ptr, 3), 0)
Expand Down
100 changes: 86 additions & 14 deletions volpe/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@


# All these initializations are required for code generation!
from volpe_types import int1, int32, flt32, flt64, VolpeTuple, VolpeClosure
from volpe_types import (
int1,
int32,
flt32,
flt64,
VolpeTuple,
VolpeClosure,
VolpeIterator,
VolpeList
)

llvm.initialize()
llvm.initialize_native_target()
Expand Down Expand Up @@ -38,28 +47,91 @@ def compile_and_run(llvm_ir, result_type):


def determine_c_type(volpe_type, depth=0):
# Interpret result type.
"""Interpret the volpe type and return a corresponding C type."""
# Simple types:
if volpe_type == int1:
return c_bool
if volpe_type == int32:
return c_int32
if volpe_type == flt32:
return c_float
if volpe_type == flt64:
return c_double

# Aggregate types:
if isinstance(volpe_type, VolpeTuple):
elems = volpe_type.elements
class CTuple(Structure):
_fields_ = [(f"elem{i}", determine_c_type(elem, depth+1)) for i, elem in enumerate(elems)]
def __repr__(self):
return "[" + ", ".join([str(getattr(self, tup[0])) for tup in self._fields_]) + "]"

return POINTER(CTuple) if depth == 0 else CTuple

if isinstance(volpe_type, VolpeList):
element_type = determine_c_type(volpe_type.element_type, depth+1)
class CList(Structure):
_fields_ = [("elems", POINTER(element_type)), ("length", c_int32)]
def __repr__(self):
if depth == 0:
elems = getattr(self, "elems")
length = getattr(self, "length")
return "&<" + ", ".join([str(elem) for elem in elems[:length]]) + ">"
return get_type_name(volpe_type)
return POINTER(CList) if depth == 0 else CList

if isinstance(volpe_type, VolpeClosure):
elems = volpe_type.elements
class CFunc(Structure):
_fields_ = [("func", POINTER(None)), ("c_func", POINTER(None)), ("f_func", POINTER(None)), ("env", POINTER(None))]
def __repr__(self):
return "*function*"
if depth == 0:
func = elems[0].pointee
input_type = ", ".join([get_type_name(i) for i in func.args[1:]])
return_type = get_type_name(func.return_type)
return f"function ({input_type}) => {return_type}"
return get_type_name(volpe_type)
return CFunc
elif volpe_type == int1:
return c_bool
elif volpe_type == int32:
return c_int32
elif volpe_type == flt32:
return c_float
elif volpe_type == flt64:
return c_double
else:
return None

if isinstance(volpe_type, VolpeIterator):
class CFunc(Structure):
_fields_ = [("func", POINTER(None)), ("c_func", POINTER(None)), ("f_func", POINTER(None)), ("env", POINTER(None))]
class CIterator(Structure):
_fields_ = [("func", CFunc), ("length", c_int32)]
def __repr__(self):
if depth == 0:
# TODO maybe include length?
func = volpe_type.elements[0].elements[0].pointee
return_type = get_type_name(func.return_type)
return f"iterator of {return_type}"
return get_type_name(volpe_type)
return CIterator

# Unknown type
return None


def get_type_name(volpe_type):
"""Get short Volpe names for types."""
# Simple types:
if volpe_type == int1:
return "bool"
if volpe_type == int32:
return "int32"
if volpe_type == flt32:
return "flt32"
if volpe_type == flt64:
return "flt64"

# Aggregate types:
if isinstance(volpe_type, VolpeTuple):
type_reprs = ", ".join([get_type_name(elem) for elem in volpe_type.elements])
return f"[{type_reprs}]"
if isinstance(volpe_type, VolpeList):
return "*list*"
if isinstance(volpe_type, VolpeClosure):
return "*function*"
if isinstance(volpe_type, VolpeIterator):
return "*iterator*"

# Unknown type
return None
7 changes: 4 additions & 3 deletions volpe/run_volpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from builder_utils import build_func
from compile import compile_and_run
from tree import TypeTree
from volpe_types import pint8, int32, VolpeTuple, target_data, VolpeClosure, copy_func, free_func
from volpe_types import pint8, int32, VolpeTuple, VolpeList, target_data, VolpeClosure, copy_func, free_func


def volpe_llvm(tree: TypeTree, verbose=False, fast=False):
Expand Down Expand Up @@ -55,17 +55,18 @@ def scope(name):
b.ret_void()

return_type = func_type.func.return_type
if isinstance(return_type, VolpeTuple):
if isinstance(return_type, (VolpeTuple, VolpeList)):
return_type = return_type.as_pointer()

main_func = ir.Function(module, ir.FunctionType(return_type, []), "main")
with build_func(main_func) as (b, _):
b: ir.IRBuilder
res = b.call(func, [pint8(ir.Undefined)])
if isinstance(res.type, VolpeTuple):
if isinstance(res.type, (VolpeTuple, VolpeList)):
ptr = b.bitcast(b.call(module.malloc, [int32(res.type.get_abi_size(target_data))]), return_type)
b.store(res, ptr)
res = ptr
# TODO return list and vector as pointer
b.ret(res)

if verbose:
Expand Down