1
This commit is contained in:
Christoph
2021-08-31 15:19:10 +02:00
parent b9fbc45494
commit 125e6dd260
4 changed files with 71 additions and 65 deletions

View File

@ -1,14 +1,26 @@
object nil: object nil:
1 1
def pass: def pass:
nil nil
object inttrait: object inttrait:
def eq(other):
self $int_eq(other)
def leq(other):
self $int_leq(other)
def geq(other):
self $int_geq(other)
def greater(other):
self $int_greater(other)
def less(other):
self $int_less(other)
def add(other): def add(other):
self $int_add(other) self $int_add(other)
# Project: Sugar
def sub(other): def sub(other):
self $int_sub(other) self $int_sub(other)
def mul(other): def mul(other):
@ -20,18 +32,6 @@ object inttrait:
def inc: def inc:
self $int_inc self $int_inc
# Project: Boolean
def eq(other):
self $int_eq(other)
def leq(other):
self $int_leq(other)
def geq(other):
self $int_geq(other)
def greater(other):
self $int_greater(other)
def less(other):
self $int_less(other)
def tobool: def tobool:
self $int_tobool self $int_tobool
def tostr: def tostr:
@ -39,8 +39,11 @@ object inttrait:
def todouble: def todouble:
self $int_todouble self $int_todouble
# Project: Boolean
object booltrait: object booltrait:
def eq(other):
self $bool_eq(other)
def and(other): def and(other):
self $bool_and(other) self $bool_and(other)
def or(other): def or(other):
@ -55,10 +58,11 @@ object booltrait:
def todouble: def todouble:
self $bool_todouble self $bool_todouble
# Project: String
object strtrait: object strtrait:
def eq(other): def eq(other):
self $str_eq(other) self $str_eq(other)
def add(other): def add(other):
self $str_add(other) self $str_add(other)
def rev: def rev:
@ -73,10 +77,11 @@ object strtrait:
def todouble: def todouble:
self $str_todouble self $str_todouble
# Project: Double
object doubletrait: object doubletrait:
def eq(other): def eq(other):
self $double_eq(other) self $double_eq(other)
def add(other): def add(other):
self $double_add(other) self $double_add(other)
def sub(other): def sub(other):

View File

@ -1,37 +1,36 @@
registry = {} registry = {} # names are keys
all_primitives = [] all_primitives = []
primitive_number_of_arguments = [] primitive_number_of_arguments = []
def primitive(name, unwrap_spec, wrap_spec): # decorator arguments def primitive(name, unwrap_spec, wrap_spec): # decorator args
assert '$' + name not in registry, '${name} already defined'.format(name=name) assert '$' + name not in registry, '${name} already defined'.format(name=name)
primitive_number_of_arguments.append(len(unwrap_spec) - 1) # first argument is the receiver primitive_number_of_arguments.append(len(unwrap_spec) - 1) # first argument is the receiver
def expose(func): # decorator def expose(func): # decorator
def unwrapper(w_receiver, args_w, space): def unwrapper(w_receiver, args_w, space):
args = [w_receiver] + args_w args = [w_receiver] + args_w
if len(args) != len(unwrap_spec): # check that call args match primitive args if len(args) != len(unwrap_spec): # call args match primitive args
raise TypeError( raise TypeError("Expected {ex} arguments, received {re}.".format(ex=len(unwrap_spec), re=len(args)))
"Expected {ex} arguments, received {re}.".format(ex=len(unwrap_spec), re=len(args)))
unwrapped_args = () unwrapped_args = ()
for t, arg in zip(unwrap_spec, args): # unpack values from simple-objects for t, arg in zip(unwrap_spec, args): # unpack
if t in [int, str, float]: # Project: Double, String if t in [int, str, float]:
unwrapped_args += (arg.value,) unwrapped_args += (arg.value,)
elif t is bool: # Project: Boolean elif t is bool:
unwrapped_args += (bool(arg.value),) # isn't really necessary because "1 or 0" is also valid unwrapped_args += (bool(arg.value),)
else: else:
unwrapped_args += (arg,) unwrapped_args += (arg,)
result = func(*unwrapped_args) # actual call result = func(*unwrapped_args) # actual call
if wrap_spec is int: # wrap the result if wrap_spec is int: # wrap
return space.newint(result) return space.newint(result)
elif wrap_spec is bool: # Project: Boolean elif wrap_spec is bool:
return space.newbool(result) return space.newbool(result)
elif wrap_spec is str: # Project: String elif wrap_spec is str:
return space.newstring(result) return space.newstring(result)
elif wrap_spec is float: # Project: Double elif wrap_spec is float:
return space.newdouble(result) return space.newdouble(result)
return result return result
@ -51,12 +50,37 @@ def get_number_of_arguments_of_primitive(idx):
return primitive_number_of_arguments[idx] return primitive_number_of_arguments[idx]
# int
@primitive("int_eq", [int, int], bool)
def simple_int_eq(a, b):
return a == b
@primitive("int_leq", [int, int], bool)
def simple_int_leq(a, b):
return a <= b
@primitive("int_geq", [int, int], bool)
def simple_int_geq(a, b):
return a >= b
@primitive("int_greater", [int, int], bool)
def simple_int_greater(a, b):
return a > b
@primitive("int_less", [int, int], bool)
def simple_int_less(a, b):
return a < b
@primitive('int_add', [int, int], int) @primitive('int_add', [int, int], int)
def simple_int_add(a, b): def simple_int_add(a, b):
return a + b return a + b
# Project: Sugar
@primitive("int_sub", [int, int], int) @primitive("int_sub", [int, int], int)
def simple_int_subtract(a, b): def simple_int_subtract(a, b):
return a - b return a - b
@ -82,23 +106,27 @@ def simple_int_increment(a):
return a + 1 return a + 1
# Project: Boolean, String, Double
@primitive("int_tobool", [int], bool) @primitive("int_tobool", [int], bool)
def simple_int_tobool(a): def simple_int_tobool(a):
return a return a
@primitive("int_tostr", [int], str) @primitive("int_tostr", [int], str)
def simple_int_tobstr(a): def simple_int_tostr(a):
return a return a
@primitive("int_todouble", [int], float) @primitive("int_todouble", [int], float)
def simple_int_tobdouble(a): def simple_int_todouble(a):
return a return a
# Project: Boolean # bool
@primitive("bool_eq", [bool, bool], bool)
def simple_bool_eq(a, b):
return a is b
@primitive("bool_and", [bool, bool], bool) @primitive("bool_and", [bool, bool], bool)
def simple_bool_and(a, b): def simple_bool_and(a, b):
return a and b return a and b
@ -129,33 +157,7 @@ def simple_bool_todouble(a):
return a return a
# bool stuff for int # string
@primitive("int_eq", [int, int], bool)
def simple_int_eq(a, b):
return a == b
@primitive("int_leq", [int, int], bool)
def simple_int_leq(a, b):
return a <= b
@primitive("int_geq", [int, int], bool)
def simple_int_geq(a, b):
return a >= b
@primitive("int_greater", [int, int], bool)
def simple_int_greater(a, b):
return a > b
@primitive("int_less", [int, int], bool)
def simple_int_less(a, b):
return a < b
# Project: String
@primitive("str_eq", [str, str], bool) @primitive("str_eq", [str, str], bool)
def simple_str_eq(a, b): def simple_str_eq(a, b):
return a == b return a == b
@ -191,7 +193,7 @@ def simple_str_todouble(a):
return a return a
# Project: Double # double
@primitive("double_eq", [float, float], bool) @primitive("double_eq", [float, float], bool)
def simple_double_eq(a, b): def simple_double_eq(a, b):
return a == b return a == b

View File

@ -1,4 +1,3 @@
import py
from rply import Token from rply import Token
from simpleast import Program, ExprStatement, BooleanLiteral, Assignment, ImplicitSelf from simpleast import Program, ExprStatement, BooleanLiteral, Assignment, ImplicitSelf
@ -69,6 +68,7 @@ y = 1 leq(2)
def test_boolean_conversion(): def test_boolean_conversion():
ast = parse(""" ast = parse("""
w = 1 tostr
x = 1 tobool x = 1 tobool
y = true toint y = true toint
z = false toint z = false toint

View File

@ -1,4 +1,3 @@
import py
from rply import Token from rply import Token
from simpleast import Program, ExprStatement, BooleanLiteral, ImplicitSelf, Assignment, StringLiteral from simpleast import Program, ExprStatement, BooleanLiteral, ImplicitSelf, Assignment, StringLiteral