# HG changeset patch # User Paul Boddie # Date 1490448386 -3600 # Node ID 00e902870a29e330395ad4b1536d98f4b8259dc6 # Parent 09f0039c42cb9f54c99a25735df4db2168128049# Parent 08cde2ca66ca7515c96a602b6352ddb81fdd6d2c Merged changes from the normal-function-parameters branch, making it the default line of development from now on. diff -r 09f0039c42cb -r 00e902870a29 common.py --- a/common.py Fri Mar 24 18:52:59 2017 +0100 +++ b/common.py Sat Mar 25 14:26:26 2017 +0100 @@ -562,7 +562,6 @@ # = {n.list} # = .__iter__() - # = .next compiler.ast.Assign( [compiler.ast.AssName(t0, "OP_ASSIGN")], @@ -574,13 +573,9 @@ compiler.ast.Getattr(compiler.ast.Name(t0), "__iter__"), [])), - compiler.ast.Assign( - [compiler.ast.AssName(i0, "OP_ASSIGN")], - compiler.ast.Getattr(compiler.ast.Name(t1), "next")), - # try: # while True: - # ... = () + # ... = .next() # ... # except StopIteration: # pass @@ -592,7 +587,7 @@ compiler.ast.Assign( [n.assign], compiler.ast.CallFunc( - compiler.ast.Name(i0), + compiler.ast.Getattr(compiler.ast.Name(t1), "next"), [] )), n.body]), diff -r 09f0039c42cb -r 00e902870a29 generator.py --- a/generator.py Fri Mar 24 18:52:59 2017 +0100 +++ b/generator.py Sat Mar 25 14:26:26 2017 +0100 @@ -43,6 +43,7 @@ # NOTE: These must be synchronised with the library. function_type = "__builtins__.core.function" + int_type = "__builtins__.int.int" none_type = "__builtins__.none.NoneType" string_type = "__builtins__.str.string" type_type = "__builtins__.core.type" @@ -154,6 +155,8 @@ f_decls = open(join(self.output, "progtypes.h"), "w") f_signatures = open(join(self.output, "main.h"), "w") f_code = open(join(self.output, "main.c"), "w") + f_calls = open(join(self.output, "calls.c"), "w") + f_call_macros = open(join(self.output, "calls.h"), "w") try: # Output boilerplate. @@ -193,6 +196,14 @@ #include "progtypes.h" #include "main.h" #include "progops.h" +#include "calls.h" +""" + + print >>f_call_macros, """\ +#ifndef __CALLS_H__ +#define __CALLS_H__ + +#include "types.h" """ # Generate table and structure data. @@ -302,15 +313,18 @@ extra_function_instances.append(path) # Write function declarations. - # Signature: __attr (__attr[]); + # Signature: __attr (...); - print >>f_signatures, "__attr %s(__attr args[]);" % encode_function_pointer(path) + parameters = self.importer.function_parameters[path] + l = ["__attr"] * (len(parameters) + 1) + print >>f_signatures, "__attr %s(%s);" % (encode_function_pointer(path), ", ".join(l)) # Generate parameter table size data. min_parameters = {} max_parameters = {} size_parameters = {} + all_max_parameters = set() # Consolidate parameter tables for instantiators and functions. @@ -339,6 +353,7 @@ min_parameters[signature] = argmin max_parameters[signature] = argmax size_parameters[signature] = len(parameters) + all_max_parameters.add(argmax) self.write_size_constants(f_consts, "pmin", min_parameters, 0) self.write_size_constants(f_consts, "pmax", max_parameters, 0) @@ -359,6 +374,11 @@ for constant, n in self.optimiser.constants.items(): self.make_literal_constant(f_decls, f_defs, n, constant) + # Generate a common integer instance object, referenced when integer + # attributes are accessed. + + self.make_common_integer(f_decls, f_defs) + # Finish the main source file. self.write_main_program(f_code, f_signatures) @@ -398,6 +418,42 @@ self.optimiser.locations, "code", "pos", encode_code, encode_pos) + # Generate macros for calls. + + all_max_parameters = list(all_max_parameters) + all_max_parameters.sort() + + for argmax in all_max_parameters: + l = [] + argnum = 0 + while argnum < argmax: + l.append("ARGS[%d]" % argnum) + argnum += 1 + + print >>f_call_macros, "#define __CALL%d(FN, ARGS) (FN(%s))" % (argmax, ", ".join(l)) + + # Generate a generic invocation function. + + print >>f_call_macros, "__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n);" + + print >>f_calls, """\ +#include "types.h" +#include "calls.h" + +__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n) +{ + switch (n) + {""" + + for argmax in all_max_parameters: + print >>f_calls, """\ + case %d: return __CALL%d(fn, args);""" % (argmax, argmax) + + print >>f_calls, """\ + default: return __NULL; + } +}""" + # Output more boilerplate. print >>f_consts, """\ @@ -424,12 +480,18 @@ #endif /* __MAIN_H__ */""" + print >>f_call_macros, """\ + +#endif /* __CALLS_H__ */""" + finally: f_consts.close() f_defs.close() f_decls.close() f_signatures.close() f_code.close() + f_calls.close() + f_call_macros.close() def write_scripts(self, debug, gc_sections): @@ -504,6 +566,11 @@ value, value_type, encoding = constant + # Do not generate individual integer constants. + + if value_type == self.int_type: + return + const_path = encode_literal_constant(n) structure_name = encode_literal_reference(n) @@ -526,13 +593,23 @@ self.make_constant(f_decls, f_defs, ref, attr_path, structure_name) + def make_common_integer(self, f_decls, f_defs): + + """ + Write common integer instance details to 'f_decls' (to declare a + structure) and to 'f_defs' (to define the contents). + """ + + ref = Reference("", self.int_type) + self.make_constant(f_decls, f_defs, ref, "__common_integer", "__common_integer_obj") + def make_constant(self, f_decls, f_defs, ref, const_path, structure_name, data=None, encoding=None): """ Write constant details to 'f_decls' (to declare a structure) and to 'f_defs' (to define the contents) for the constant described by 'ref' - having the given 'path' and 'structure_name' (for the constant structure - itself). + having the given 'const_path' (providing an attribute for the constant) + and 'structure_name' (for the constant structure itself). The additional 'data' and 'encoding' are used to describe specific values. @@ -974,7 +1051,7 @@ # Special internal size member. elif attrname == "__size__": - structure.append("{.intvalue=%d}" % attr) + structure.append("__INTVALUE(%d)" % attr) continue # Special internal key member. @@ -1081,6 +1158,13 @@ # Obtain a constant value directly assigned to the attribute. if self.optimiser.constant_numbers.has_key(alias): + + # Encode integer constants differently. + + value, value_type, encoding = self.importer.all_constant_values[alias] + if value_type == self.int_type: + return "__INTVALUE(%s) /* %s */" % (value, name) + constant_number = self.optimiser.constant_numbers[alias] constant_value = encode_literal_constant(constant_number) return "%s /* %s */" % (constant_value, name) @@ -1127,57 +1211,52 @@ NOTE: where __call__ is provided by the class. """ - parameters = self.importer.function_parameters[init_ref.get_origin()] + initialiser = init_ref.get_origin() + parameters = self.importer.function_parameters[initialiser] + argmin, argmax = self.get_argument_limits(initialiser) + + l = [] + for name in parameters: + l.append("__attr %s" % name) print >>f_code, """\ -__attr %s(__attr __args[]) +__attr %s(__attr __self%s) { - /* Allocate the structure. */ - __args[0] = __NEWINSTANCE(%s); - - /* Call the initialiser. */ - %s(__args); - - /* Return the allocated object details. */ - return __args[0]; + return %s(__NEWINSTANCE(%s)%s); } """ % ( - encode_instantiator_pointer(path), - encode_path(path), - encode_function_pointer(init_ref.get_origin()) - ) + encode_instantiator_pointer(path), + l and ", %s" % ",".join(l) or "", + encode_function_pointer(initialiser), + encode_path(path), + parameters and ", %s" % ", ".join(parameters) or "" + ) + + # Signature: __new_typename(__attr __self, ...) + + print >>f_signatures, "__attr %s(__attr __self%s);" % ( + encode_instantiator_pointer(path), + l and ", %s" % ", ".join(l) or "" + ) print >>f_signatures, "#define __HAVE_%s" % encode_path(path) - print >>f_signatures, "__attr %s(__attr[]);" % encode_instantiator_pointer(path) # Write additional literal instantiators. These do not call the # initialisers but instead populate the structures directly. + # Signature: __newliteral_sequence(ARGS, NUM) + if path in self.literal_instantiator_types: if path in self.literal_mapping_types: style = "mapping" else: style = "sequence" - print >>f_code, """\ -__attr %s(__attr __args[], __pos number) -{ - /* Allocate the structure. */ - __args[0] = __NEWINSTANCE(%s); - - /* Allocate a structure for the data and set it on the __data__ attribute. */ - %s(__args, number); - - /* Return the allocated object details. */ - return __args[0]; -} -""" % ( - encode_literal_instantiator(path), - encode_path(path), - encode_literal_data_initialiser(style) - ) - - print >>f_signatures, "__attr %s(__attr[], __pos);" % encode_literal_instantiator(path) + print >>f_signatures, "#define %s(ARGS, NUM) (%s(__NEWINSTANCE(%s), ARGS, NUM))" % ( + encode_literal_instantiator(path), + encode_literal_data_initialiser(style), + encode_path(path) + ) def write_main_program(self, f_code, f_signatures): @@ -1213,13 +1292,11 @@ __Catch(__tmp_exc) { if (__ISINSTANCE(__tmp_exc.arg, __ATTRVALUE(&__builtins___exception_system_SystemExit))) - return __load_via_object( - __load_via_object(__tmp_exc.arg.value, __data__).value, - value).intvalue; + return __TOINT(__load_via_object(__VALUE(__tmp_exc.arg), value)); fprintf(stderr, "Program terminated due to exception: %%s.\\n", __load_via_object( - %s(__ARGS(__NULL, __tmp_exc.arg)).value, + __VALUE(%s(__NULL, __tmp_exc.arg)), __data__).strvalue); return 1; } diff -r 09f0039c42cb -r 00e902870a29 lib/__builtins__/character.py --- a/lib/__builtins__/character.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/__builtins__/character.py Sat Mar 25 14:26:26 2017 +0100 @@ -29,7 +29,7 @@ check_int(i) if 0 <= i <= 255: - return str_chr(i.__data__) + return str_chr(i) else: raise ValueError, i @@ -94,7 +94,7 @@ check_int(i) if 0 <= i <= 2097151: - return utf8string(unicode_unichr(i.__data__)) + return utf8string(unicode_unichr(i)) else: raise ValueError, i diff -r 09f0039c42cb -r 00e902870a29 lib/__builtins__/int.py --- a/lib/__builtins__/int.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/__builtins__/int.py Sat Mar 25 14:26:26 2017 +0100 @@ -3,7 +3,7 @@ """ Integer objects. -Copyright (C) 2015, 2016 Paul Boddie +Copyright (C) 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -34,11 +34,9 @@ "Initialise the integer with the given 'number_or_string'." - if _isinstance(number_or_string, int): - self.__data__ = number_or_string.__data__ - else: - # NOTE: To be implemented. - self.__data__ = None + # NOTE: To be implemented. + + pass def __hash__(self): @@ -51,7 +49,7 @@ "Perform 'op' on this int and 'other' if appropriate." if _isinstance(other, int): - return op(self.__data__, other.__data__) + return op(self, other) else: return NotImplemented @@ -60,7 +58,7 @@ "Perform 'op' on 'other' and this int if appropriate." if _isinstance(other, int): - return op(other.__data__, self.__data__) + return op(other, self) else: return NotImplemented @@ -122,7 +120,7 @@ "Return the inversion of this int." - return int_not(self.__data__) + return int_not(self) __add__ = __radd__ = __iadd__ __sub__ = __isub__ @@ -206,7 +204,7 @@ "Apply the unary negation operator." - return int_neg(self.__data__) + return int_neg(self) def __pos__(self): @@ -218,7 +216,7 @@ "Return a string representation." - return utf8string(int_str(self.__data__)) + return utf8string(int_str(self)) __repr__ = __str__ @@ -233,8 +231,7 @@ "Return whether this int is non-zero." - zero = 0 - return int_ne(self.__data__, zero.__data__) + return int_ne(self, 0) # Limits. diff -r 09f0039c42cb -r 00e902870a29 lib/__builtins__/str.py --- a/lib/__builtins__/str.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/__builtins__/str.py Sat Mar 25 14:26:26 2017 +0100 @@ -22,7 +22,7 @@ from __builtins__.operator import _negate from __builtins__.sequence import hashable, itemaccess from __builtins__.types import check_int -from native import int_new, str_add, str_lt, str_gt, str_eq, str_ord, \ +from native import str_add, str_lt, str_gt, str_eq, str_ord, \ str_substr WHITESPACE = (" ", "\f", "\n", "\r", "\t") @@ -53,7 +53,7 @@ else: self.__data__ = None self.__key__ = None - self.__size__ = None + self.__size__ = 0 # Internal methods. @@ -157,7 +157,7 @@ "Return the number of bytes in this string." - return int_new(self.__size__) + return self.__size__ # General type methods. @@ -165,7 +165,7 @@ "Return whether the string provides any data." - return int_new(self.__size__).__bool__() + return self.__size__.__bool__() def __contains__(self, value): diff -r 09f0039c42cb -r 00e902870a29 lib/native/__init__.py --- a/lib/native/__init__.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/native/__init__.py Sat Mar 25 14:26:26 2017 +0100 @@ -23,10 +23,10 @@ from native.identity import is_, is_not -from native.int import int_new, \ - int_add, int_div, int_mod, int_mul, int_neg, int_pow, \ - int_sub, int_and, int_not, int_or, int_xor, int_lt, \ - int_gt, int_eq, int_ne, int_str +from native.int import int_add, int_div, int_mod, int_mul, int_neg, int_pow, \ + int_sub, int_and, int_not, int_or, int_xor, \ + int_eq, int_ge, int_gt, int_le, int_lt, int_ne, \ + int_str, is_int from native.introspection import object_getattr, isinstance, issubclass diff -r 09f0039c42cb -r 00e902870a29 lib/native/int.py --- a/lib/native/int.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/native/int.py Sat Mar 25 14:26:26 2017 +0100 @@ -24,7 +24,7 @@ this program. If not, see . """ -def int_new(data): pass +def is_int(obj): pass def int_add(self, other): pass def int_div(self, other): pass @@ -39,9 +39,11 @@ def int_or(self, other): pass def int_xor(self, other): pass -def int_lt(self, other): pass +def int_eq(self, other): pass +def int_ge(self, other): pass def int_gt(self, other): pass -def int_eq(self, other): pass +def int_le(self, other): pass +def int_lt(self, other): pass def int_ne(self, other): pass def int_str(self): pass diff -r 09f0039c42cb -r 00e902870a29 lib/operator/augmented.py --- a/lib/operator/augmented.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/operator/augmented.py Sat Mar 25 14:26:26 2017 +0100 @@ -3,7 +3,7 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,6 +20,9 @@ """ from operator.core import augassign +from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \ + int_and, int_or, int_xor, \ + is_int # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -31,12 +34,18 @@ # Augmented assignment functions. def iadd(a, b): + if is_int(a) and is_int(b): + return int_add(a, b) return augassign(a, b, lambda a: a.__iadd__, lambda a: a.__add__, lambda b: b.__radd__) def iand_(a, b): + if is_int(a) and is_int(b): + return int_and(a, b) return augassign(a, b, lambda a: a.__iand__, lambda a: a.__and__, lambda b: b.__rand__) def idiv(a, b): + if is_int(a) and is_int(b): + return int_div(a, b) return augassign(a, b, lambda a: a.__idiv__, lambda a: a.__div__, lambda b: b.__rdiv__) def ifloordiv(a, b): @@ -46,24 +55,36 @@ return augassign(a, b, lambda a: a.__ilshift__, lambda a: a.__lshift__, lambda b: b.__rlshift__) def imod(a, b): + if is_int(a) and is_int(b): + return int_mod(a, b) return augassign(a, b, lambda a: a.__imod__, lambda a: a.__mod__, lambda b: b.__rmod__) def imul(a, b): + if is_int(a) and is_int(b): + return int_mul(a, b) return augassign(a, b, lambda a: a.__imul__, lambda a: a.__mul__, lambda b: b.__rmul__) def ior_(a, b): + if is_int(a) and is_int(b): + return int_or(a, b) return augassign(a, b, lambda a: a.__ior__, lambda a: a.__or__, lambda b: b.__ror__) def ipow(a, b): + if is_int(a) and is_int(b): + return int_pow(a, b) return augassign(a, b, lambda a: a.__ipow__, lambda a: a.__pow__, lambda b: b.__rpow__) def irshift(a, b): return augassign(a, b, lambda a: a.__irshift__, lambda a: a.__rshift__, lambda b: b.__rrshift__) def isub(a, b): + if is_int(a) and is_int(b): + return int_sub(a, b) return augassign(a, b, lambda a: a.__isub__, lambda a: a.__sub__, lambda b: b.__rsub__) def ixor(a, b): + if is_int(a) and is_int(b): + return int_xor(a, b) return augassign(a, b, lambda a: a.__ixor__, lambda a: a.__xor__, lambda b: b.__rxor__) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 09f0039c42cb -r 00e902870a29 lib/operator/binary.py --- a/lib/operator/binary.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/operator/binary.py Sat Mar 25 14:26:26 2017 +0100 @@ -3,7 +3,7 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,6 +20,9 @@ """ from operator.core import binary_op, is_, is_not +from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \ + int_and, int_not, int_or, int_xor, \ + is_int # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -28,15 +31,21 @@ # Binary operator functions. def add(a, b): + if is_int(a) and is_int(b): + return int_add(a, b) return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__) def and_(a, b): + if is_int(a) and is_int(b): + return int_and(a, b) return binary_op(a, b, lambda a: a.__and__, lambda b: b.__rand__) def contains(a, b): return in_(b, a) def div(a, b): + if is_int(a) and is_int(b): + return int_div(a, b) return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__) def floordiv(a, b): @@ -52,24 +61,36 @@ return binary_op(a, b, lambda a: a.__lshift__, lambda b: b.__rlshift__) def mod(a, b): + if is_int(a) and is_int(b): + return int_mod(a, b) return binary_op(a, b, lambda a: a.__mod__, lambda b: b.__rmod__) def mul(a, b): + if is_int(a) and is_int(b): + return int_mul(a, b) return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__) def or_(a, b): + if is_int(a) and is_int(b): + return int_or(a, b) return binary_op(a, b, lambda a: a.__or__, lambda b: b.__ror__) def pow(a, b): + if is_int(a) and is_int(b): + return int_pow(a, b) return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__) def rshift(a, b): return binary_op(a, b, lambda a: a.__rshift__, lambda b: b.__rrshift__) def sub(a, b): + if is_int(a) and is_int(b): + return int_sub(a, b) return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__) def xor(a, b): + if is_int(a) and is_int(b): + return int_xor(a, b) return binary_op(a, b, lambda a: a.__xor__, lambda b: b.__rxor__) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 09f0039c42cb -r 00e902870a29 lib/operator/comparison.py --- a/lib/operator/comparison.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/operator/comparison.py Sat Mar 25 14:26:26 2017 +0100 @@ -3,7 +3,7 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,6 +20,7 @@ """ from operator.core import binary_op +from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -28,21 +29,33 @@ # Comparison functions. def eq(a, b): + if is_int(a) and is_int(b): + return int_eq(a, b) return binary_op(a, b, lambda a: a.__eq__, lambda b: b.__eq__, False) def ge(a, b): + if is_int(a) and is_int(b): + return int_ge(a, b) return binary_op(a, b, lambda a: a.__ge__, lambda b: b.__le__) def gt(a, b): + if is_int(a) and is_int(b): + return int_gt(a, b) return binary_op(a, b, lambda a: a.__gt__, lambda b: b.__lt__) def le(a, b): + if is_int(a) and is_int(b): + return int_le(a, b) return binary_op(a, b, lambda a: a.__le__, lambda b: b.__ge__) def lt(a, b): + if is_int(a) and is_int(b): + return int_lt(a, b) return binary_op(a, b, lambda a: a.__lt__, lambda b: b.__gt__) def ne(a, b): + if is_int(a) and is_int(b): + return int_ne(a, b) return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__, True) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 09f0039c42cb -r 00e902870a29 lib/operator/unary.py --- a/lib/operator/unary.py Fri Mar 24 18:52:59 2017 +0100 +++ b/lib/operator/unary.py Sat Mar 25 14:26:26 2017 +0100 @@ -3,7 +3,7 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,6 +20,7 @@ """ from operator.core import unary_op +from native.int import int_neg, int_not, is_int # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -31,12 +32,18 @@ return unary_op(a, lambda a: a.__invert__) def neg(a): + if is_int(a): + return int_neg(a) return unary_op(a, lambda a: a.__neg__) def not_(a): + if is_int(a): + return int_not(a) return not a def pos(a): + if is_int(a): + return a return unary_op(a, lambda a: a.__pos__) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 09f0039c42cb -r 00e902870a29 templates/Makefile --- a/templates/Makefile Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/Makefile Sat Mar 25 14:26:26 2017 +0100 @@ -2,7 +2,7 @@ include modules.mk include options.mk -SRC += exceptions.c main.c ops.c progops.c progtypes.c +SRC += calls.c exceptions.c main.c ops.c progops.c progtypes.c OBJ = $(SRC:.c=.o) CFLAGS += -Wall -I. -finput-charset=UTF-8 LDFLAGS += -lm -lgc diff -r 09f0039c42cb -r 00e902870a29 templates/native/buffer.c --- a/templates/native/buffer.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/buffer.c Sat Mar 25 14:26:26 2017 +0100 @@ -26,18 +26,17 @@ #include "progtypes.h" #include "main.h" -__attr __fn_native_buffer_buffer_str(__attr __args[]) +__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as buffer */ - __fragment *data = _data->seqvalue; + /* _data interpreted as buffer.__data__ */ + __fragment *data = _data.seqvalue; unsigned int size = 0, i, j, n; char *s; __attr o; /* Calculate the size of the string. */ for (i = 0; i < data->size; i++) - size += __load_via_object(data->attrs[i].value, __size__).intvalue; + size += __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__)); /* Reserve space for a new string. */ s = (char *) __ALLOCATE(size + 1, sizeof(char)); @@ -45,8 +44,8 @@ /* Build a single string from the buffer contents. */ for (i = 0, j = 0; i < data->size; i++) { - o = __load_via_object(data->attrs[i].value, __data__); - n = __load_via_object(data->attrs[i].value, __size__).intvalue; + o = __load_via_object(__VALUE(data->attrs[i]), __data__); + n = __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__)); memcpy(s + j, o.strvalue, n); /* does not null terminate but final byte should be zero */ j += n; } diff -r 09f0039c42cb -r 00e902870a29 templates/native/buffer.h --- a/templates/native/buffer.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/buffer.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for buffer operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,7 +23,7 @@ /* Buffer operations. */ -__attr __fn_native_buffer_buffer_str(__attr __args[]); +__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/common.c --- a/templates/native/common.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/common.c Sat Mar 25 14:26:26 2017 +0100 @@ -26,20 +26,12 @@ /* Utility functions. */ -__attr __new_int(int i) -{ - /* Create a new integer and mutate the __data__ attribute. */ - __attr attr = __NEWINSTANCEIM(__builtins___int_int); - attr.value->attrs[__ATTRPOS(__data__)].intvalue = i; - return attr; -} - __attr __new_str(char *s, int size) { /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */ __attr attr = __NEWINSTANCE(__builtins___str_string); attr.value->attrs[__ATTRPOS(__data__)].strvalue = s; - attr.value->attrs[__ATTRPOS(__size__)].intvalue = size; + attr.value->attrs[__ATTRPOS(__size__)] = __INTVALUE(size); attr.value->attrs[__ATTRPOS(__key__)] = __NULL; return attr; } @@ -52,7 +44,7 @@ return attr; } -__fragment *__fragment_append(__fragment *data, __attr * const value) +__fragment *__fragment_append(__fragment *data, __attr value) { __fragment *newdata = data; unsigned int size = data->size, capacity = data->capacity; @@ -68,7 +60,7 @@ } /* Insert the new element and increment the list size. */ - newdata->attrs[size] = *value; + newdata->attrs[size] = value; newdata->size = size + 1; return newdata; diff -r 09f0039c42cb -r 00e902870a29 templates/native/common.h --- a/templates/native/common.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/common.h Sat Mar 25 14:26:26 2017 +0100 @@ -23,9 +23,9 @@ /* Utility functions. */ -__attr __new_int(int i); +#define __new_int(VALUE) __INTVALUE(VALUE) __attr __new_str(char *s, int size); __attr __new_list(__fragment *f); -__fragment *__fragment_append(__fragment *data, __attr * const value); +__fragment *__fragment_append(__fragment *data, __attr value); #endif /* __NATIVE_COMMON_H__ */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/iconv.c --- a/templates/native/iconv.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/iconv.c Sat Mar 25 14:26:26 2017 +0100 @@ -33,37 +33,31 @@ static void __raise_incomplete_sequence_error(__attr value, __attr arg) { #ifdef __HAVE_posix_iconv_IncompleteSequenceError - __attr args[3] = {__NULL, value, arg}; - __attr exc = __new_posix_iconv_IncompleteSequenceError(args); - __Raise(exc); + __Raise(__new_posix_iconv_IncompleteSequenceError(__NULL, value, arg)); #endif /* __HAVE_posix_iconv_IncompleteSequenceError */ } static void __raise_invalid_sequence_error(__attr value, __attr arg) { #ifdef __HAVE_posix_iconv_InvalidSequenceError - __attr args[3] = {__NULL, value, arg}; - __attr exc = __new_posix_iconv_InvalidSequenceError(args); - __Raise(exc); + __Raise(__new_posix_iconv_InvalidSequenceError(__NULL, value, arg)); #endif /* __HAVE_posix_iconv_InvalidSequenceError */ } /* Character set conversion. */ -__attr __fn_native_iconv_iconv(__attr __args[]) +__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state) { - __attr * const cd = &__args[1]; - __attr * const state = &__args[2]; /* cd interpreted as iconv_t */ - iconv_t c = (iconv_t) cd->datavalue; + iconv_t c = (iconv_t) cd.datavalue; /* state.__data__ interpreted as list */ - __fragment *f = __load_via_object(state->value, __data__).seqvalue; + __fragment *f = __load_via_object(__VALUE(state), __data__).seqvalue; /* Obtain the string, start position, and remaining bytes from the state. */ - char *inbuf = __load_via_object(f->attrs[0].value, __data__).strvalue; - int start = __load_via_object(f->attrs[1].value, __data__).intvalue; - int remaining = __load_via_object(f->attrs[2].value, __data__).intvalue; + char *inbuf = __load_via_object(__VALUE(f->attrs[0]), __data__).strvalue; + int start = __TOINT(f->attrs[1]); + int remaining = __TOINT(f->attrs[2]); /* Allocate a string for the output buffer using the remaining input size as a guide. */ @@ -123,11 +117,10 @@ return __builtins___none_None; } -__attr __fn_native_iconv_iconv_close(__attr __args[]) +__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd) { - __attr * const cd = &__args[1]; /* cd interpreted as iconv_t */ - iconv_t c = (iconv_t) cd->datavalue; + iconv_t c = (iconv_t) cd.datavalue; errno = 0; @@ -137,14 +130,12 @@ return __builtins___none_None; } -__attr __fn_native_iconv_iconv_open(__attr __args[]) +__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode) { - __attr * const tocode = &__args[1]; - __attr * const fromcode = &__args[2]; /* tocode.__data__ interpreted as string */ - char *t = __load_via_object(tocode->value, __data__).strvalue; + char *t = __load_via_object(__VALUE(tocode), __data__).strvalue; /* fromcode.__data__ interpreted as string */ - char *f = __load_via_object(fromcode->value, __data__).strvalue; + char *f = __load_via_object(__VALUE(fromcode), __data__).strvalue; iconv_t result; __attr attr; @@ -160,11 +151,10 @@ return attr; } -__attr __fn_native_iconv_iconv_reset(__attr __args[]) +__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd) { - __attr * const cd = &__args[1]; /* cd interpreted as iconv_t */ - iconv_t c = (iconv_t) cd->datavalue; + iconv_t c = (iconv_t) cd.datavalue; iconv(c, NULL, NULL, NULL, NULL); return __builtins___none_None; diff -r 09f0039c42cb -r 00e902870a29 templates/native/iconv.h --- a/templates/native/iconv.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/iconv.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for character set conversion. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,10 +23,10 @@ /* Input/output. */ -__attr __fn_native_iconv_iconv(__attr __args[]); -__attr __fn_native_iconv_iconv_close(__attr __args[]); -__attr __fn_native_iconv_iconv_open(__attr __args[]); -__attr __fn_native_iconv_iconv_reset(__attr __args[]); +__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state); +__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd); +__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode); +__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/identity.c --- a/templates/native/identity.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/identity.c Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for identity operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,20 +26,18 @@ /* Identity testing. */ -__attr __fn_native_identity_is_(__attr __args[]) +__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y) { - __attr * const x = &__args[1]; - __attr * const y = &__args[2]; + /* NOTE: value member assumed equivalent to intvalue for comparison. */ - return x->value == y->value ? __builtins___boolean_True : __builtins___boolean_False; + return x.value == y.value ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_identity_is_not(__attr __args[]) +__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y) { - __attr * const x = &__args[1]; - __attr * const y = &__args[2]; + /* NOTE: value member assumed equivalent to intvalue for comparison. */ - return x->value != y->value ? __builtins___boolean_True : __builtins___boolean_False; + return x.value != y.value ? __builtins___boolean_True : __builtins___boolean_False; } /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/identity.h --- a/templates/native/identity.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/identity.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for identity operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Identity testing. */ -__attr __fn_native_identity_is_(__attr __args[]); -__attr __fn_native_identity_is_not(__attr __args[]); +__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y); +__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/int.c --- a/templates/native/int.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/int.c Sat Mar 25 14:26:26 2017 +0100 @@ -16,7 +16,6 @@ this program. If not, see . */ -#include /* INT_MAX, INT_MIN */ #include /* ceil, log10, pow */ #include /* fdopen, snprintf */ #include /* errno */ @@ -32,24 +31,20 @@ /* Integer operations. */ -__attr __fn_native_int_int_new(__attr __args[]) +__attr __fn_native_int_is_int(__attr __self, __attr obj) { - __attr * const _data = &__args[1]; - - return __new_int(_data->intvalue); + return __INTEGER(obj) ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_add(__attr __args[]) +__attr __fn_native_int_int_add(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Test for overflow. */ - if (((i > 0) && (j > 0) && (i > INT_MAX - j)) || - ((i < 0) && (j < 0) && (i < INT_MIN - j))) + if (((i > 0) && (j > 0) && (i > __MAXINT - j)) || + ((i < 0) && (j < 0) && (i < __MININT - j))) __raise_overflow_error(); @@ -57,17 +52,15 @@ return __new_int(i + j); } -__attr __fn_native_int_int_sub(__attr __args[]) +__attr __fn_native_int_int_sub(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Test for overflow. */ - if (((i < 0) && (j > 0) && (i < INT_MIN + j)) || - ((i > 0) && (j < 0) && (i > INT_MAX + j))) + if (((i < 0) && (j > 0) && (i < __MININT + j)) || + ((i > 0) && (j < 0) && (i > __MAXINT + j))) __raise_overflow_error(); @@ -75,19 +68,17 @@ return __new_int(i - j); } -__attr __fn_native_int_int_mul(__attr __args[]) +__attr __fn_native_int_int_mul(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Test for overflow. */ - if (((i > 0) && (j > 0) && (i > INT_MAX / j)) || - ((i < 0) && (j < 0) && (i > INT_MAX / j)) || - ((i < 0) && (j > 0) && (i < INT_MIN / j)) || - ((i > 0) && (j < 0) && (j < INT_MIN / i))) + if (((i > 0) && (j > 0) && (i > __MAXINT / j)) || + ((i < 0) && (j < 0) && (i > __MAXINT / j)) || + ((i < 0) && (j > 0) && (i < __MININT / j)) || + ((i > 0) && (j < 0) && (j < __MININT / i))) __raise_overflow_error(); @@ -95,63 +86,56 @@ return __new_int(i * j); } -__attr __fn_native_int_int_div(__attr __args[]) +__attr __fn_native_int_int_div(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Test for division by zero or overflow. */ if (j == 0) __raise_zero_division_error(); - else if ((j == -1) && (i == INT_MIN)) + else if ((j == -1) && (i == __MININT)) __raise_overflow_error(); /* Return the new integer. */ return __new_int(i / j); } -__attr __fn_native_int_int_mod(__attr __args[]) +__attr __fn_native_int_int_mod(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Test for division by zero or overflow. */ if (j == 0) __raise_zero_division_error(); - else if ((j == -1) && (i == INT_MIN)) + else if ((j == -1) && (i == __MININT)) __raise_overflow_error(); /* Return the new integer. */ return __new_int(i % j); } -__attr __fn_native_int_int_neg(__attr __args[]) +__attr __fn_native_int_int_neg(__attr __self, __attr self) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* self interpreted as int */ + int i = __TOINT(self); /* Test for overflow. */ - if (i == INT_MIN) + if (i == __MININT) __raise_overflow_error(); /* Return the new integer. */ return __new_int(-i); } -__attr __fn_native_int_int_pow(__attr __args[]) +__attr __fn_native_int_int_pow(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); int k; errno = 0; @@ -166,111 +150,116 @@ return __new_int(k); } -__attr __fn_native_int_int_and(__attr __args[]) +__attr __fn_native_int_int_and(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return the new integer. */ /* NOTE: No overflow test applied. */ return __new_int(i & j); } -__attr __fn_native_int_int_not(__attr __args[]) +__attr __fn_native_int_int_not(__attr __self, __attr self) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* self interpreted as int */ + int i = __TOINT(self); /* Return the new integer. */ return __new_int(~i); } -__attr __fn_native_int_int_or(__attr __args[]) +__attr __fn_native_int_int_or(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return the new integer. */ /* NOTE: No overflow test applied. */ return __new_int(i | j); } -__attr __fn_native_int_int_xor(__attr __args[]) +__attr __fn_native_int_int_xor(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return the new integer. */ /* NOTE: No overflow test applied. */ return __new_int(i ^ j); } -__attr __fn_native_int_int_lt(__attr __args[]) +__attr __fn_native_int_int_le(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); + + /* Return a boolean result. */ + return i <= j ? __builtins___boolean_True : __builtins___boolean_False; +} + +__attr __fn_native_int_int_lt(__attr __self, __attr self, __attr other) +{ + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return a boolean result. */ return i < j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_gt(__attr __args[]) +__attr __fn_native_int_int_ge(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); + + /* Return a boolean result. */ + return i >= j ? __builtins___boolean_True : __builtins___boolean_False; +} + +__attr __fn_native_int_int_gt(__attr __self, __attr self, __attr other) +{ + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return a boolean result. */ return i > j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_eq(__attr __args[]) +__attr __fn_native_int_int_eq(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return a boolean result. */ return i == j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_ne(__attr __args[]) +__attr __fn_native_int_int_ne(__attr __self, __attr self, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); /* Return a boolean result. */ return i != j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_str(__attr __args[]) +__attr __fn_native_int_int_str(__attr __self, __attr self) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* self interpreted as int */ + int i = __TOINT(self); + /* Employ a buffer big enough to fit the largest integer plus an extra character, a minus sign, and the null terminator. */ - unsigned int n = (int) log10(INT_MAX) + 3; + unsigned int n = (int) log10(__MAXINT) + 3; char *s = (char *) __ALLOCATE(n, sizeof(char)); snprintf(s, n, "%d", i); diff -r 09f0039c42cb -r 00e902870a29 templates/native/int.h --- a/templates/native/int.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/int.h Sat Mar 25 14:26:26 2017 +0100 @@ -23,32 +23,28 @@ /* Integer operations. */ -__attr __fn_native_int_int_new(__attr __args[]); - -__attr __fn_native_int_int_add(__attr __args[]); -__attr __fn_native_int_int_div(__attr __args[]); -__attr __fn_native_int_int_mod(__attr __args[]); -__attr __fn_native_int_int_mul(__attr __args[]); -__attr __fn_native_int_int_neg(__attr __args[]); -__attr __fn_native_int_int_pow(__attr __args[]); -__attr __fn_native_int_int_sub(__attr __args[]); +__attr __fn_native_int_is_int(__attr __self, __attr obj); +__attr __fn_native_int_int_add(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_sub(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_mul(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_div(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_mod(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_neg(__attr __self, __attr _data); +__attr __fn_native_int_int_pow(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_and(__attr __args[]); -__attr __fn_native_int_int_not(__attr __args[]); -__attr __fn_native_int_int_or(__attr __args[]); -__attr __fn_native_int_int_xor(__attr __args[]); +__attr __fn_native_int_int_and(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_not(__attr __self, __attr _data); +__attr __fn_native_int_int_or(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_xor(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_rdiv(__attr __args[]); -__attr __fn_native_int_int_rmod(__attr __args[]); -__attr __fn_native_int_int_rpow(__attr __args[]); -__attr __fn_native_int_int_rsub(__attr __args[]); +__attr __fn_native_int_int_eq(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_ge(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_le(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_lt(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_ne(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_lt(__attr __args[]); -__attr __fn_native_int_int_gt(__attr __args[]); -__attr __fn_native_int_int_eq(__attr __args[]); -__attr __fn_native_int_int_ne(__attr __args[]); - -__attr __fn_native_int_int_str(__attr __args[]); +__attr __fn_native_int_int_str(__attr __self, __attr _data); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/introspection.c --- a/templates/native/introspection.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/introspection.c Sat Mar 25 14:26:26 2017 +0100 @@ -26,56 +26,47 @@ /* Introspection. */ -__attr __fn_native_introspection_object_getattr(__attr __args[]) +__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default) { - __attr * const obj = &__args[1]; - __attr * const name = &__args[2]; - __attr * const _default = &__args[3]; - /* name.__data__ interpreted as string */ - __attr key = __load_via_object(name->value, __key__); + /* name interpreted as string */ + __attr key = __load_via_object(__VALUE(name), __key__); __attr out; if ((key.code == 0) && (key.pos == 0)) - return *_default; + return _default; /* Attempt to get the attribute from the object. */ - out = __check_and_load_via_object_null(obj->value, key.pos, key.code); - if (out.value == 0) + out = __check_and_load_via_object_null(__VALUE(obj), key.pos, key.code); + if (__ISNULL(out)) { /* Inspect the object's class if this failed. */ - out = __check_and_load_via_class__(obj->value, key.pos, key.code); - if (out.value == 0) - return *_default; + out = __check_and_load_via_class__(__VALUE(obj), key.pos, key.code); + if (__ISNULL(out)) + return _default; /* Update the context to the object if it is a method. */ - return __update_context(*obj, out); + return __update_context(obj, out); } return out; } -__attr __fn_native_introspection_isinstance(__attr __args[]) +__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls) { - __attr * const obj = &__args[1]; - __attr * const cls = &__args[2]; - /* cls must be a class. */ - if (__is_instance_subclass(obj->value, *cls)) + if (__is_instance_subclass(__VALUE(obj), cls)) return __builtins___boolean_True; else return __builtins___boolean_False; } -__attr __fn_native_introspection_issubclass(__attr __args[]) +__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls) { - __attr * const obj = &__args[1]; - __attr * const cls = &__args[2]; - /* obj and cls must be classes. */ - if (__is_subclass(obj->value, *cls)) + if (__is_subclass(__VALUE(obj), cls)) return __builtins___boolean_True; else return __builtins___boolean_False; diff -r 09f0039c42cb -r 00e902870a29 templates/native/introspection.h --- a/templates/native/introspection.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/introspection.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for introspection. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,9 +23,9 @@ /* Introspection. */ -__attr __fn_native_introspection_object_getattr(__attr __args[]); -__attr __fn_native_introspection_isinstance(__attr __args[]); -__attr __fn_native_introspection_issubclass(__attr __args[]); +__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default); +__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls); +__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/io.c --- a/templates/native/io.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/io.c Sat Mar 25 14:26:26 2017 +0100 @@ -31,11 +31,10 @@ /* Input/output. */ -__attr __fn_native_io_fclose(__attr __args[]) +__attr __fn_native_io_fclose(__attr __self, __attr fp) { - __attr * const fp = &__args[1]; /* fp interpreted as FILE reference */ - FILE *f = (FILE *) fp->datavalue; + FILE *f = (FILE *) fp.datavalue; errno = 0; if (fclose(f)) @@ -44,11 +43,10 @@ return __builtins___none_None; } -__attr __fn_native_io_fflush(__attr __args[]) +__attr __fn_native_io_fflush(__attr __self, __attr fp) { - __attr * const fp = &__args[1]; /* fp interpreted as FILE reference */ - FILE *f = (FILE *) fp->datavalue; + FILE *f = (FILE *) fp.datavalue; errno = 0; if (fflush(f)) @@ -57,14 +55,12 @@ return __builtins___none_None; } -__attr __fn_native_io_fopen(__attr __args[]) +__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode) { - __attr * const filename = &__args[1]; - __attr * const mode = &__args[2]; /* filename.__data__ interpreted as string */ - char *fn = __load_via_object(filename->value, __data__).strvalue; + char *fn = __load_via_object(__VALUE(filename), __data__).strvalue; /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __data__).strvalue; + char *s = __load_via_object(__VALUE(mode), __data__).strvalue; FILE *f; __attr attr; @@ -89,14 +85,12 @@ return __builtins___none_None; } -__attr __fn_native_io_fdopen(__attr __args[]) +__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode) { - __attr * const fd = &__args[1]; - __attr * const mode = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __data__).intvalue; + /* fd interpreted as int */ + int i = __TOINT(fd); /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __data__).strvalue; + char *s = __load_via_object(__VALUE(mode), __data__).strvalue; FILE *f; __attr attr; @@ -121,14 +115,12 @@ return __builtins___none_None; } -__attr __fn_native_io_fread(__attr __args[]) +__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size) { - __attr * const fp = &__args[1]; - __attr * const size = &__args[2]; /* fp interpreted as FILE reference */ - FILE *f = (FILE *) fp->datavalue; - /* size.__data__ interpreted as int */ - int to_read = __load_via_object(size->value, __data__).intvalue; + FILE *f = (FILE *) fp.datavalue; + /* size interpreted as int */ + int to_read = __TOINT(size); char buf[to_read]; size_t have_read; int error; @@ -151,16 +143,14 @@ return __new_str(s, have_read); } -__attr __fn_native_io_fwrite(__attr __args[]) +__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str) { - __attr * const fp = &__args[1]; - __attr * const str = &__args[2]; /* fp interpreted as FILE reference */ - FILE *f = (FILE *) fp->datavalue; + FILE *f = (FILE *) fp.datavalue; /* str.__data__ interpreted as string */ - char *s = __load_via_object(str->value, __data__).strvalue; + char *s = __load_via_object(__VALUE(str), __data__).strvalue; /* str.__size__ interpreted as int */ - int to_write = __load_via_object(str->value, __size__).intvalue; + int to_write = __TOINT(__load_via_object(__VALUE(str), __size__)); size_t have_written = fwrite(s, sizeof(char), to_write, f); int error; @@ -175,11 +165,10 @@ return __builtins___none_None; } -__attr __fn_native_io_close(__attr __args[]) +__attr __fn_native_io_close(__attr __self, __attr fd) { - __attr * const fd = &__args[1]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __data__).intvalue; + /* fd interpreted as int */ + int i = __TOINT(fd); errno = 0; if (close(i) == -1) @@ -188,14 +177,12 @@ return __builtins___none_None; } -__attr __fn_native_io_read(__attr __args[]) +__attr __fn_native_io_read(__attr __self, __attr fd, __attr n) { - __attr * const fd = &__args[1]; - __attr * const n = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __data__).intvalue; - /* n.__data__ interpreted as int */ - int to_read = __load_via_object(n->value, __data__).intvalue; + /* fd interpreted as int */ + int i = __TOINT(fd); + /* n interpreted as int */ + int to_read = __TOINT(n); char buf[to_read]; ssize_t have_read; char *s; @@ -213,16 +200,14 @@ return __new_str(s, have_read); } -__attr __fn_native_io_write(__attr __args[]) +__attr __fn_native_io_write(__attr __self, __attr fd, __attr str) { - __attr * const fd = &__args[1]; - __attr * const str = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __data__).intvalue; + /* fd interpreted as int */ + int i = __TOINT(fd); /* str.__data__ interpreted as string */ - char *s = __load_via_object(str->value, __data__).strvalue; + char *s = __load_via_object(__VALUE(str), __data__).strvalue; /* str.__size__ interpreted as int */ - int size = __load_via_object(str->value, __size__).intvalue; + int size = __TOINT(__load_via_object(__VALUE(str), __size__)); ssize_t have_written; errno = 0; diff -r 09f0039c42cb -r 00e902870a29 templates/native/io.h --- a/templates/native/io.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/io.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for input/output. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,15 +23,15 @@ /* Input/output. */ -__attr __fn_native_io_fclose(__attr __args[]); -__attr __fn_native_io_fflush(__attr __args[]); -__attr __fn_native_io_fopen(__attr __args[]); -__attr __fn_native_io_fdopen(__attr __args[]); -__attr __fn_native_io_fread(__attr __args[]); -__attr __fn_native_io_fwrite(__attr __args[]); -__attr __fn_native_io_close(__attr __args[]); -__attr __fn_native_io_read(__attr __args[]); -__attr __fn_native_io_write(__attr __args[]); +__attr __fn_native_io_fclose(__attr __self, __attr fp); +__attr __fn_native_io_fflush(__attr __self, __attr fp); +__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode); +__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode); +__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size); +__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str); +__attr __fn_native_io_close(__attr __self, __attr fd); +__attr __fn_native_io_read(__attr __self, __attr fd, __attr n); +__attr __fn_native_io_write(__attr __self, __attr fd, __attr str); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/limits.c --- a/templates/native/limits.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/limits.c Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for limit definition. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -16,7 +16,6 @@ this program. If not, see . */ -#include /* INT_MAX, INT_MIN */ #include "native/common.h" #include "types.h" #include "exceptions.h" @@ -28,14 +27,14 @@ /* Limit definition. */ -__attr __fn_native_limits_get_maxint(__attr __args[]) +__attr __fn_native_limits_get_maxint(__attr __self) { - return __new_int(INT_MAX); + return __new_int(__MAXINT); } -__attr __fn_native_limits_get_minint(__attr __args[]) +__attr __fn_native_limits_get_minint(__attr __self) { - return __new_int(INT_MIN); + return __new_int(__MININT); } /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/limits.h --- a/templates/native/limits.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/limits.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for limit definition. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Limit definition. */ -__attr __fn_native_limits_get_maxint(__attr __args[]); -__attr __fn_native_limits_get_minint(__attr __args[]); +__attr __fn_native_limits_get_maxint(__attr __self); +__attr __fn_native_limits_get_minint(__attr __self); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/list.c --- a/templates/native/list.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/list.c Sat Mar 25 14:26:26 2017 +0100 @@ -27,51 +27,44 @@ /* List operations. */ -__attr __fn_native_list_list_init(__attr __args[]) +__attr __fn_native_list_list_init(__attr __self, __attr size) { - __attr * const size = &__args[1]; - /* size.__data__ interpreted as int */ - unsigned int n = __load_via_object(size->value, __data__).intvalue; + /* size interpreted as int */ + unsigned int n = __TOINT(size); __attr attr = {.seqvalue=__new_fragment(n)}; /* Return the __data__ attribute. */ return attr; } -__attr __fn_native_list_list_setsize(__attr __args[]) +__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size) { - __attr * const _data = &__args[1]; - __attr * const size = &__args[2]; - /* _data interpreted as list */ - __fragment *data = _data->seqvalue; - /* size.__data__ interpreted as int */ - unsigned int n = __load_via_object(size->value, __data__).intvalue; + /* _data interpreted as list.__data__ */ + __fragment *data = _data.seqvalue; + /* size interpreted as int */ + unsigned int n = __TOINT(size); data->size = n; return __builtins___none_None; } -__attr __fn_native_list_list_append(__attr __args[]) +__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value) { - __attr * const self = &__args[1]; - __attr * const value = &__args[2]; /* self.__data__ interpreted as list */ - __fragment *data = __load_via_object(self->value, __data__).seqvalue; + __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue; __fragment *newdata = __fragment_append(data, value); /* Replace the __data__ attribute if appropriate. */ if (newdata != data) - __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata})); + __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata})); return __builtins___none_None; } -__attr __fn_native_list_list_concat(__attr __args[]) +__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other) { - __attr * const self = &__args[1]; - __attr * const other = &__args[2]; - /* self.__data__, other interpreted as list */ - __fragment *data = __load_via_object(self->value, __data__).seqvalue; - __fragment *other_data = other->seqvalue; + /* self, interpreted as list, other interpreted as list.__data__ */ + __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue; + __fragment *other_data = other.seqvalue; __fragment *newdata = data; unsigned int size = data->size, capacity = data->capacity; unsigned int other_size = other_data->size; @@ -91,51 +84,43 @@ /* Replace the __data__ attribute if appropriate. */ if (newdata != data) - __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata})); + __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata})); return __builtins___none_None; } -__attr __fn_native_list_list_len(__attr __args[]) +__attr __fn_native_list_list_len(__attr self, __attr _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as fragment */ - unsigned int size = _data->seqvalue->size; + /* _data interpreted as list.__data__ */ + unsigned int size = _data.seqvalue->size; /* Return the new integer. */ return __new_int(size); } -__attr __fn_native_list_list_nonempty(__attr __args[]) +__attr __fn_native_list_list_nonempty(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - - return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; + return _data.seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_list_list_element(__attr __args[]) +__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index) { - __attr * const _data = &__args[1]; - __attr * const index = &__args[2]; - /* _data interpreted as fragment */ - __attr *elements = _data->seqvalue->attrs; - /* index.__data__ interpreted as int */ - int i = __load_via_object(index->value, __data__).intvalue; + /* _data interpreted as list.__data__ */ + __attr *elements = _data.seqvalue->attrs; + /* index interpreted as int */ + int i = __TOINT(index); return elements[i]; } -__attr __fn_native_list_list_setelement(__attr __args[]) +__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value) { - __attr * const _data = &__args[1]; - __attr * const index = &__args[2]; - __attr * const value = &__args[3]; - /* _data interpreted as fragment */ - __attr *elements = _data->seqvalue->attrs; - /* index.__data__ interpreted as int */ - int i = __load_via_object(index->value, __data__).intvalue; + /* _data interpreted as list.__data__ */ + __attr *elements = _data.seqvalue->attrs; + /* index interpreted as int */ + int i = __TOINT(index); /* Set the element. */ - elements[i] = *value; + elements[i] = value; return __builtins___none_None; } diff -r 09f0039c42cb -r 00e902870a29 templates/native/list.h --- a/templates/native/list.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/list.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for list operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,14 +23,14 @@ /* List operations. */ -__attr __fn_native_list_list_init(__attr __args[]); -__attr __fn_native_list_list_setsize(__attr __args[]); -__attr __fn_native_list_list_append(__attr __args[]); -__attr __fn_native_list_list_concat(__attr __args[]); -__attr __fn_native_list_list_len(__attr __args[]); -__attr __fn_native_list_list_nonempty(__attr __args[]); -__attr __fn_native_list_list_element(__attr __args[]); -__attr __fn_native_list_list_setelement(__attr __args[]); +__attr __fn_native_list_list_init(__attr __self, __attr size); +__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size); +__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value); +__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other); +__attr __fn_native_list_list_len(__attr self, __attr _data); +__attr __fn_native_list_list_nonempty(__attr __self, __attr _data); +__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index); +__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/locale.c --- a/templates/native/locale.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/locale.c Sat Mar 25 14:26:26 2017 +0100 @@ -29,11 +29,10 @@ /* Locales. */ -__attr __fn_native_locale_getlocale(__attr __args[]) +__attr __fn_native_locale_getlocale(__attr __self, __attr category) { - __attr * const category = &__args[1]; - /* category.__data__ interpreted as int */ - int cat = __load_via_object(category->value, __data__).intvalue; + /* category interpreted as int */ + int cat = __TOINT(category); char *result, *out; size_t length; @@ -49,14 +48,12 @@ return __new_str(result, length); } -__attr __fn_native_locale_setlocale(__attr __args[]) +__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value) { - __attr * const category = &__args[1]; - __attr * const value = &__args[2]; - /* category.__data__ interpreted as int */ - int cat = __load_via_object(category->value, __data__).intvalue; - /* value.__data__ interpreted as string */ - char *s = __load_via_object(value->value, __data__).strvalue; + /* category interpreted as int */ + int cat = __TOINT(category); + /* value interpreted as string */ + char *s = __load_via_object(__VALUE(value), __data__).strvalue; char *result, *out; size_t length; diff -r 09f0039c42cb -r 00e902870a29 templates/native/locale.h --- a/templates/native/locale.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/locale.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for locale handling. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Input/output. */ -__attr __fn_native_locale_getlocale(__attr __args[]); -__attr __fn_native_locale_setlocale(__attr __args[]); +__attr __fn_native_locale_getlocale(__attr __self, __attr category); +__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/program.c --- a/templates/native/program.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/program.c Sat Mar 25 14:26:26 2017 +0100 @@ -26,12 +26,9 @@ /* Method binding. */ -__attr __fn_native_program_get_using(__attr __args[]) +__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance) { - __attr * const callable = &__args[1]; - __attr * const instance = &__args[2]; - - return __test_context(*instance, *callable); + return __test_context(instance, callable); } /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/program.h --- a/templates/native/program.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/program.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for program operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -21,7 +21,7 @@ /* Method binding. */ -__attr __fn_native_program_get_using(__attr __args[]); +__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/str.c --- a/templates/native/str.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/str.c Sat Mar 25 14:26:26 2017 +0100 @@ -28,16 +28,13 @@ /* String operations. */ -__attr __fn_native_str_str_add(__attr __args[]) +__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - __attr * const _size = &__args[3]; - __attr * const othersize = &__args[4]; - /* _data, other interpreted as string */ - char *s = _data->strvalue; - char *o = other->strvalue; - int ss = _size->intvalue, os = othersize->intvalue; + /* _data, other interpreted as string.__data__ */ + char *s = _data.strvalue; + char *o = other.strvalue; + /* _size, othersize interpreted as int */ + int ss = __TOINT(_size), os = __TOINT(othersize); int n = ss + os; char *r = (char *) __ALLOCATE(n + 1, sizeof(char)); @@ -48,76 +45,64 @@ return __new_str(r, n); } -__attr __fn_native_str_str_chr(__attr __args[]) +__attr __fn_native_str_str_chr(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int n = _data->intvalue; + /* data interpreted as int */ + int n = __TOINT(_data); char *s = (char *) __ALLOCATE(2, sizeof(char)); s[0] = (char) n; return __new_str(s, 1); } -__attr __fn_native_str_str_lt(__attr __args[]) +__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - char *s = _data->strvalue; - char *o = other->strvalue; + /* _data, other interpreted as string.__data__ */ + char *s = _data.strvalue; + char *o = other.strvalue; /* NOTE: Using simple byte-level string operations. */ return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_gt(__attr __args[]) +__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - char *s = _data->strvalue; - char *o = other->strvalue; + /* _data, other interpreted as string.__data__ */ + char *s = _data.strvalue; + char *o = other.strvalue; /* NOTE: Using simple byte-level string operations. */ return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_eq(__attr __args[]) +__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other) { - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - char *s = _data->strvalue; - char *o = other->strvalue; + /* _data, other interpreted as string.__data__ */ + char *s = _data.strvalue; + char *o = other.strvalue; /* NOTE: Using simple byte-level string operations. */ return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_ord(__attr __args[]) +__attr __fn_native_str_str_ord(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as string */ - char *s = _data->strvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue; return __new_int((unsigned int) s[0]); } -__attr __fn_native_str_str_substr(__attr __args[]) +__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step) { - __attr * const _data = &__args[1]; - __attr * const start = &__args[2]; - __attr * const end = &__args[3]; - __attr * const step = &__args[4]; - /* _data interpreted as string */ - char *s = _data->strvalue, *sub; - /* start.__data__ interpreted as int */ - int istart = __load_via_object(start->value, __data__).intvalue; - /* end.__data__ interpreted as int */ - int iend = __load_via_object(end->value, __data__).intvalue; - /* step.__data__ interpreted as int */ - int istep = __load_via_object(step->value, __data__).intvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue, *sub; + /* start interpreted as int */ + int istart = __TOINT(start); + /* end interpreted as int */ + int iend = __TOINT(end); + /* step interpreted as int */ + int istep = __TOINT(step); /* Calculate the size of the substring. */ size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; diff -r 09f0039c42cb -r 00e902870a29 templates/native/str.h --- a/templates/native/str.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/str.h Sat Mar 25 14:26:26 2017 +0100 @@ -21,13 +21,13 @@ /* String operations. */ -__attr __fn_native_str_str_add(__attr __args[]); -__attr __fn_native_str_str_chr(__attr __args[]); -__attr __fn_native_str_str_lt(__attr __args[]); -__attr __fn_native_str_str_gt(__attr __args[]); -__attr __fn_native_str_str_eq(__attr __args[]); -__attr __fn_native_str_str_ord(__attr __args[]); -__attr __fn_native_str_str_substr(__attr __args[]); +__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize); +__attr __fn_native_str_str_chr(__attr __self, __attr _data); +__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_ord(__attr __self, __attr _data); +__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/system.c --- a/templates/native/system.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/system.c Sat Mar 25 14:26:26 2017 +0100 @@ -27,21 +27,19 @@ /* Environment support. */ -__attr __fn_native_system_exit(__attr __args[]) +__attr __fn_native_system_exit(__attr __self, __attr status) { - __attr * const status = &__args[1]; - - exit(__load_via_object(status->value, __data__).intvalue); + exit(__TOINT(status)); return __builtins___none_None; } -__attr __fn_native_system_get_argv(__attr __args[]) +__attr __fn_native_system_get_argv(__attr __self) { /* NOTE: To be written. */ return __builtins___none_None; } -__attr __fn_native_system_get_path(__attr __args[]) +__attr __fn_native_system_get_path(__attr __self) { /* NOTE: To be written. */ return __builtins___none_None; diff -r 09f0039c42cb -r 00e902870a29 templates/native/system.h --- a/templates/native/system.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/system.h Sat Mar 25 14:26:26 2017 +0100 @@ -1,6 +1,6 @@ /* Native functions for system operations. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,9 +23,9 @@ /* Environment support. */ -__attr __fn_native_system_exit(__attr __args[]); -__attr __fn_native_system_get_argv(__attr __args[]); -__attr __fn_native_system_get_path(__attr __args[]); +__attr __fn_native_system_exit(__attr __self, __attr status); +__attr __fn_native_system_get_argv(__attr __self); +__attr __fn_native_system_get_path(__attr __self); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/native/unicode.c --- a/templates/native/unicode.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/unicode.c Sat Mar 25 14:26:26 2017 +0100 @@ -69,14 +69,12 @@ /* Unicode operations. */ -__attr __fn_native_unicode_unicode_len(__attr __args[]) +__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size) { - __attr * const _data = &__args[1]; - __attr * const _size = &__args[2]; - /* _data interpreted as string */ - char *s = _data->strvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue; /* _size interpreted as int */ - int size = _size->intvalue; + int size = __TOINT(_size); unsigned int i, c = 0; for (i = 0; i < size; i++) @@ -87,14 +85,12 @@ return __new_int(c); } -__attr __fn_native_unicode_unicode_ord(__attr __args[]) +__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size) { - __attr * const _data = &__args[1]; - __attr * const _size = &__args[2]; - /* _data interpreted as string */ - char *s = _data->strvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue; /* _size interpreted as int */ - int size = _size->intvalue; + int size = __TOINT(_size); unsigned int i, c = 0, v; for (i = 0; i < size; i++) @@ -123,23 +119,18 @@ return __new_int(c); } -__attr __fn_native_unicode_unicode_substr(__attr __args[]) +__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step) { - __attr * const _data = &__args[1]; - __attr * const _size = &__args[2]; - __attr * const start = &__args[3]; - __attr * const end = &__args[4]; - __attr * const step = &__args[5]; - /* _data interpreted as string */ - char *s = _data->strvalue, *sub; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue, *sub; /* _size interpreted as int */ - int ss = _size->intvalue; - /* start.__data__ interpreted as int */ - int istart = __load_via_object(start->value, __data__).intvalue; - /* end.__data__ interpreted as int */ - int iend = __load_via_object(end->value, __data__).intvalue; - /* step.__data__ interpreted as int */ - int istep = __load_via_object(step->value, __data__).intvalue; + int ss = __TOINT(_size); + /* start interpreted as int */ + int istart = __TOINT(start); + /* end interpreted as int */ + int iend = __TOINT(end); + /* step interpreted as int */ + int istep = __TOINT(step); /* Calculate the number of characters. */ size_t nchar = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; @@ -202,11 +193,10 @@ return __new_str(sub, resultsize); } -__attr __fn_native_unicode_unicode_unichr(__attr __args[]) +__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value) { - __attr * const value = &__args[1]; /* value interpreted as int */ - int i = value->intvalue; + int i = __TOINT(value); unsigned int resultsize; char *s; diff -r 09f0039c42cb -r 00e902870a29 templates/native/unicode.h --- a/templates/native/unicode.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/native/unicode.h Sat Mar 25 14:26:26 2017 +0100 @@ -21,10 +21,10 @@ /* Unicode operations. */ -__attr __fn_native_unicode_unicode_len(__attr __args[]); -__attr __fn_native_unicode_unicode_ord(__attr __args[]); -__attr __fn_native_unicode_unicode_substr(__attr __args[]); -__attr __fn_native_unicode_unicode_unichr(__attr __args[]); +__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size); +__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size); +__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step); +__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value); /* Module initialisation. */ diff -r 09f0039c42cb -r 00e902870a29 templates/ops.c --- a/templates/ops.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/ops.c Sat Mar 25 14:26:26 2017 +0100 @@ -27,7 +27,10 @@ __ref __VALUE(__attr attr) { - return attr.value; + if (!__INTEGER(attr)) + return attr.value; + else + return &__common_integer_obj; } /* Basic structure tests. */ @@ -316,17 +319,17 @@ return __VALUE(value) ? value : callable; } -__attr (*__get_function_unchecked(__attr target))(__attr[]) +__attr (*__get_function_unchecked(__attr target))() { return __load_via_object(__VALUE(__unwrap_callable(target)), __fn__).fn; } -__attr (*__get_function(__attr context, __attr target))(__attr[]) +__attr (*__get_function(__attr context, __attr target))() { return __get_function_unwrapped(context, __unwrap_callable(target)); } -__attr (*__get_function_unwrapped(__attr context, __attr target))(__attr[]) +__attr (*__get_function_unwrapped(__attr context, __attr target))() { /* Require null or instance contexts for functions and methods respectively, or type instance contexts for type methods. */ @@ -337,12 +340,12 @@ return __unbound_method; } -__attr (*__check_and_get_function(__attr context, __attr target))(__attr[]) +__attr (*__check_and_get_function(__attr context, __attr target))() { return __check_and_get_function_unwrapped(context, __unwrap_callable(target)); } -__attr (*__check_and_get_function_unwrapped(__attr context, __attr target))(__attr[]) +__attr (*__check_and_get_function_unwrapped(__attr context, __attr target))() { /* Require null or instance contexts for functions and methods respectively, or type instance contexts for type methods. */ diff -r 09f0039c42cb -r 00e902870a29 templates/ops.h --- a/templates/ops.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/ops.h Sat Mar 25 14:26:26 2017 +0100 @@ -112,11 +112,11 @@ /* Context testing for invocations. */ __attr __unwrap_callable(__attr callable); -__attr (*__get_function_unchecked(__attr target))(__attr[]); -__attr (*__get_function(__attr context, __attr target))(__attr[]); -__attr (*__get_function_unwrapped(__attr context, __attr target))(__attr[]); -__attr (*__check_and_get_function(__attr context, __attr target))(__attr[]); -__attr (*__check_and_get_function_unwrapped(__attr context, __attr target))(__attr[]); +__attr (*__get_function_unchecked(__attr target))(); +__attr (*__get_function(__attr context, __attr target))(); +__attr (*__get_function_unwrapped(__attr context, __attr target))(); +__attr (*__check_and_get_function(__attr context, __attr target))(); +__attr (*__check_and_get_function_unwrapped(__attr context, __attr target))(); /* Parameter position operations. */ diff -r 09f0039c42cb -r 00e902870a29 templates/progops.c --- a/templates/progops.c Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/progops.c Sat Mar 25 14:26:26 2017 +0100 @@ -24,6 +24,7 @@ #include "progtypes.h" #include "main.h" #include "exceptions.h" +#include "calls.h" /* Generic instantiation operations, defining common members. */ @@ -38,7 +39,7 @@ __attr __new_wrapper(__attr context, __attr attr) { - return __new___builtins___core_wrapper((__attr[]) {__NULL, context, attr}); + return __new___builtins___core_wrapper(__NULL, context, attr); } /* Generic internal data allocation. */ @@ -56,43 +57,38 @@ return data; } -void __newdata_sequence(__attr args[], unsigned int number) +__attr __newdata_sequence(__attr self, __attr args[], unsigned int number) { /* Calculate the size of the fragment. */ __fragment *data = __new_fragment(number); __attr attr = {.seqvalue=data}; - unsigned int i, j; + unsigned int i; - /* Copy the given number of values, starting from the second element. */ + /* Copy the given number of values. */ - for (i = 1, j = 0; i <= number; i++, j++) - data->attrs[j] = args[i]; + for (i = 0; i <= number; i++) + data->attrs[i] = args[i]; data->size = number; /* Store a reference to the data in the object's __data__ attribute. */ - __store_via_object(args[0].value, __data__, attr); + __store_via_object(__VALUE(self), __data__, attr); + return self; } #ifdef __HAVE___builtins___dict_dict -void __newdata_mapping(__attr args[], unsigned int number) +__attr __newdata_mapping(__attr self, __attr args[], unsigned int number) { - __attr dict = args[0]; - __attr callargs[2]; - /* Create a temporary list using the arguments. */ - __newliteral___builtins___list_list(args, number); + __attr tmp = __newliteral___builtins___list_list(args, number); /* Call __init__ with the dict object and list argument. */ - callargs[0] = dict; - callargs[1] = args[0]; - - __fn___builtins___dict_dict___init__(callargs); - args[0] = dict; + __fn___builtins___dict_dict___init__(self, tmp); + return self; } #endif /* __HAVE___builtins___dict_dict */ @@ -101,56 +97,42 @@ void __raise_eof_error() { #ifdef __HAVE___builtins___exception_io_EOFError - __attr args[1]; - __attr exc = __new___builtins___exception_io_EOFError(args); - __Raise(exc); + __Raise(__new___builtins___exception_io_EOFError(__NULL)); #endif /* __HAVE___builtins___exception_io_EOFError */ } void __raise_io_error(__attr value) { #ifdef __HAVE___builtins___exception_io_IOError - __attr args[2] = {__NULL, value}; - __attr exc = __new___builtins___exception_io_IOError(args); - __Raise(exc); + __Raise(__new___builtins___exception_io_IOError(__NULL, value)); #endif /* __HAVE___builtins___exception_io_IOError */ } void __raise_memory_error() { - __attr args[1]; - __attr exc = __new___builtins___core_MemoryError(args); - __Raise(exc); + __Raise(__new___builtins___core_MemoryError(__NULL)); } void __raise_os_error(__attr value, __attr arg) { #ifdef __HAVE___builtins___exception_system_OSError - __attr args[3] = {__NULL, value, arg}; - __attr exc = __new___builtins___exception_system_OSError(args); - __Raise(exc); + __Raise(__new___builtins___exception_system_OSError(__NULL, value, arg)); #endif /* __HAVE___builtins___exception_system_OSError */ } void __raise_overflow_error() { - __attr args[1]; - __attr exc = __new___builtins___core_OverflowError(args); - __Raise(exc); + __Raise(__new___builtins___core_OverflowError(__NULL)); } void __raise_type_error() { - __attr args[1]; - __attr exc = __new___builtins___core_TypeError(args); - __Raise(exc); + __Raise(__new___builtins___core_TypeError(__NULL)); } void __raise_zero_division_error() { - __attr args[1]; - __attr exc = __new___builtins___core_ZeroDivisionError(args); - __Raise(exc); + __Raise(__new___builtins___core_ZeroDivisionError(__NULL)); } /* Helper for raising exception instances. */ @@ -229,7 +211,7 @@ /* Erase the remaining arguments. */ for (pos = nargs; pos < max; pos++) - allargs[pos].value = 0; + __SETNULL(allargs[pos]); /* Fill keyword arguments. */ @@ -254,26 +236,26 @@ for (pos = nargs; pos < max; pos++) { - if (allargs[pos].value == 0) + if (__ISNULL(allargs[pos])) allargs[pos] = __GETDEFAULT(__VALUE(target), pos - min); } } - /* Call with the prepared arguments. */ + /* Call with the prepared arguments via a special adaptor function that + converts the array to an argument list. */ - return (always_callable ? - __get_function_unwrapped(allargs[0], target) : - __check_and_get_function_unwrapped(allargs[0], target) - )(allargs); + return __call_with_args( + always_callable ? + __get_function_unwrapped(allargs[0], target) : + __check_and_get_function_unwrapped(allargs[0], target), + allargs, max); } /* Error routines. */ -__attr __unbound_method(__attr args[]) +__attr __unbound_method(__attr __self) { - __attr excargs[1]; - __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs); - __Raise(exc); + __Raise(__new___builtins___core_UnboundMethodInvocation(__NULL)); return __builtins___none_None; /* superfluous */ } @@ -291,11 +273,10 @@ int __BOOL(__attr attr) { - __attr args[2] = {__NULL, attr}; __ref truevalue = __VALUE(__builtins___boolean_True); /* Invoke the bool function with the object and test against True. */ return (__VALUE(attr) == truevalue) || - (__VALUE(__fn___builtins___boolean_bool(args)) == truevalue); + (__VALUE(__fn___builtins___boolean_bool(__NULL, attr)) == truevalue); } diff -r 09f0039c42cb -r 00e902870a29 templates/progops.h --- a/templates/progops.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/progops.h Sat Mar 25 14:26:26 2017 +0100 @@ -21,6 +21,7 @@ #include /* size_t */ #include "types.h" +#include "main.h" /* Generic instantiation operations, defining common members. */ @@ -31,10 +32,10 @@ __fragment *__new_fragment(unsigned int n); -void __newdata_sequence(__attr args[], unsigned int number); +__attr __newdata_sequence(__attr self, __attr args[], unsigned int number); #ifdef __HAVE___builtins___dict_dict -void __newdata_mapping(__attr args[], unsigned int number); +__attr __newdata_mapping(__attr self, __attr args[], unsigned int number); #endif /* __HAVE___builtins___dict_dict */ /* Helpers for raising errors within common operations. */ @@ -60,12 +61,12 @@ /* Generic invocation operations. */ __attr __invoke(__attr callable, int always_callable, - unsigned int nkwargs, __param kwcodes[], __attr kwargs[], - unsigned int nargs, __attr args[]); + unsigned int nkwargs, __param kwcodes[], __attr kwargs[], + unsigned int nargs, __attr args[]); /* Error routines. */ -__attr __unbound_method(__attr args[]); +__attr __unbound_method(__attr __self); /* Generic operations depending on specific program details. */ @@ -79,6 +80,6 @@ #define __NEWINSTANCE(__CLS) __new(&__InstanceTable_##__CLS, &__CLS, sizeof(__obj_##__CLS), 0) #define __NEWINSTANCEIM(__CLS) __new(&__InstanceTable_##__CLS, &__CLS, sizeof(__obj_##__CLS), 1) -#define __ISINSTANCE(__ATTR, __TYPE) __BOOL(__fn_native_introspection_isinstance((__attr[]) {__NULL, __ATTR, __TYPE})) +#define __ISINSTANCE(__ATTR, __TYPE) __BOOL(__fn_native_introspection_isinstance(__NULL, __ATTR, __TYPE)) #endif /* __PROGOPS_H__ */ diff -r 09f0039c42cb -r 00e902870a29 templates/types.h --- a/templates/types.h Fri Mar 24 18:52:59 2017 +0100 +++ b/templates/types.h Sat Mar 25 14:26:26 2017 +0100 @@ -72,14 +72,19 @@ typedef union __attr { + /* General attribute members. */ + __ref value; /* attribute value */ + int intvalue; /* integer value data ((integer << 1) | 1) */ + + /* Special case attribute members. */ + const __ptable * ptable; /* parameter table */ struct { __pcode code; /* parameter table code for key */ __ppos pos; /* parameter table position for key */ }; __attr (*fn)(); /* callable details */ - int intvalue; /* integer value */ float floatvalue; /* floating point value */ char * strvalue; /* string value */ __fragment * seqvalue; /* sequence data */ @@ -106,10 +111,22 @@ #define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(unsigned int)) +/* Attribute interpretation. */ + +#define __INTEGER(ATTR) ((ATTR).intvalue % 2) + /* Attribute value setting. */ #define __ATTRVALUE(VALUE) ((__attr) {.value=VALUE}) #define __NULL __ATTRVALUE(0) +#define __SETNULL(ATTR) ((ATTR).value = 0) + +/* Attribute as instance setting. */ + +#define __INTVALUE(VALUE) ((__attr) {.intvalue=((VALUE) << 1) | 1}) +#define __TOINT(ATTR) ((ATTR).intvalue >> 1) +#define __MAXINT ((1 << ((sizeof(__attr) * 8) - 2)) - 1) +#define __MININT (-(1 << ((sizeof(__attr) * 8) - 2))) /* Argument lists. */ diff -r 09f0039c42cb -r 00e902870a29 tests/numbers.py --- a/tests/numbers.py Fri Mar 24 18:52:59 2017 +0100 +++ b/tests/numbers.py Sat Mar 25 14:26:26 2017 +0100 @@ -10,15 +10,15 @@ print "# sys.maxint + sys.minint:", print sys.maxint + sys.minint -i = 2 ** 30 -print i # 1073741824 -print hex(i) # 0x40000000 -print oct(i) # 010000000000 +i = 2 ** 29 +print i # 536870912 +print hex(i) # 0x20000000 +print oct(i) # 04000000000 -j = -2 ** 30 -print j # -1073741824 -print hex(j) # -0x40000000 -print oct(j) # -010000000000 +j = -2 ** 29 +print j # -536870912 +print hex(j) # -0x20000000 +print oct(j) # -05000000000 print i + j # 0 @@ -39,9 +39,9 @@ print i - i # 0 print j - j # 0 -print ~j # 1073741823 +print ~j # 536870911 print i & ~j # 0 -print i - 1 & ~j # 1073741823 +print i - 1 & ~j # 536870911 print hex(31) # 0x1f print oct(31) # 037 diff -r 09f0039c42cb -r 00e902870a29 translator.py --- a/translator.py Fri Mar 24 18:52:59 2017 +0100 +++ b/translator.py Sat Mar 25 14:26:26 2017 +0100 @@ -848,7 +848,12 @@ # Produce the body and any additional return statement. - expr = self.process_structure_node(n.code) or PredefinedConstantRef("None") + expr = self.process_structure_node(n.code) or \ + self.in_method() and \ + function_name.rsplit(".", 1)[-1] == "__init__" and \ + TrResolvedNameRef("self", self.importer.function_locals[function_name]["self"]) or \ + PredefinedConstantRef("None") + if not isinstance(expr, ReturnRef): self.writestmt("return %s;" % expr) @@ -882,27 +887,10 @@ else: return - # Produce an appropriate access to an attribute's value. - - name_as_attr = self.get_name_as_attribute(name) - # Write a test that raises a TypeError upon failure. self.writestmt("if (!__test_%s_%s(__VALUE(%s), %s)) __raise_type_error();" % ( - guard, guard_type, name_as_attr, argstr)) - - def get_name_as_attribute(self, name): - - "Return a generated expression for 'name' yielding an attribute." - - parameters = self.importer.function_parameters.get(self.get_namespace_path()) - parameter = name == "self" and self.in_method() or \ - parameters and name in parameters - - if parameter: - return "*%s" % encode_path(name) - else: - return "%s" % encode_path(name) + guard, guard_type, encode_path(name), argstr)) def process_function_node(self, n): @@ -1323,16 +1311,17 @@ # Encode the arguments. - argstr = "__ARGS(%s)" % ", ".join(args) + # Where literal instantiation is occurring, add an argument indicating + # the number of values. The context is excluded. + + if literal_instantiation: + argstr = "__ARGS(%s), %d" % (", ".join(args[1:]), len(args) - 1) + else: + argstr = ", ".join(args) + kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0" kwcodestr = kwcodes and ("__KWARGS(%s)" % ", ".join(kwcodes)) or "0" - # Where literal instantiation is occurring, add an argument indicating - # the number of values. - - if literal_instantiation: - argstr += ", %d" % (len(args) - 1) - # First, the invocation expression is presented. stages = [] @@ -1402,7 +1391,7 @@ target_var, self.always_callable(refs) and 1 or 0, len(kwargs), kwcodestr, kwargstr, - len(args), argstr)) + len(args), "__ARGS(%s)" % argstr)) return InvocationResult(stages) def next_target(self): @@ -1577,7 +1566,7 @@ # such names. name_ref = TrResolvedNameRef(n.name, ref, expr=expr, is_global=is_global, - parameter=parameter, location=location) + location=location) return not expr and self.get_aliases(name_ref) or name_ref def get_aliases(self, name_ref): @@ -1969,8 +1958,6 @@ "Start the function having the given 'name'." - print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name) - print >>self.out, "{" self.indent += 1 self.start_unit() @@ -1981,6 +1968,12 @@ out = self.end_unit() + # Write the signature at the top indentation level. + + self.indent -= 1 + self.write_parameters(name) + print >>self.out, "{" + # Obtain local names from parameters. parameters = self.importer.function_parameters[name] @@ -2001,7 +1994,9 @@ else: names.append(encode_path(n)) - # Emit required local names. + # Emit required local names at the function indentation level. + + self.indent += 1 if names: names.sort() @@ -2011,14 +2006,38 @@ volatile_names.sort() self.writeline("volatile __attr %s;" % ", ".join(volatile_names)) - self.write_parameters(name) - self.flush_unit(name, out) self.indent -= 1 print >>self.out, "}" print >>self.out + def write_parameters(self, name): + + """ + For the function having the given 'name', write definitions of + parameters found in the arguments array. + """ + + # Generate any self reference. + + l = [] + + if self.is_method(name): + l.append("__attr self") + else: + l.append("__attr __self") + + # Generate aliases for the parameters. + + for parameter in self.importer.function_parameters[name]: + l.append("%s__attr %s" % ( + parameter in self.volatile_locals and "volatile " or "", + encode_path(parameter))) + + self.writeline("__attr %s(%s)" % ( + encode_function_pointer(name), ", ".join(l))) + def write_temporaries(self, name): "Write temporary storage employed by 'name'." @@ -2048,27 +2067,6 @@ if name in module.exception_namespaces: self.writeline("__exc __tmp_exc;") - def write_parameters(self, name): - - """ - For the function having the given 'name', write definitions of - parameters found in the arguments array. - """ - - parameters = self.importer.function_parameters[name] - - # Generate any self reference. - - if self.is_method(name): - self.writeline("__attr * const self = &__args[0];") - - # Generate aliases for the parameters. - - for i, parameter in enumerate(parameters): - self.writeline("%s__attr * const %s = &__args[%d];" % ( - parameter in self.volatile_locals and "volatile " or "", - encode_path(parameter), i+1)) - def start_if(self, first, test_ref): statement = "%sif" % (not first and "else " or "") diff -r 09f0039c42cb -r 00e902870a29 transresults.py --- a/transresults.py Fri Mar 24 18:52:59 2017 +0100 +++ b/transresults.py Sat Mar 25 14:26:26 2017 +0100 @@ -63,9 +63,8 @@ "A reference to a name in the translation." - def __init__(self, name, ref, expr=None, is_global=False, parameter=None, location=None): + def __init__(self, name, ref, expr=None, is_global=False, location=None): ResolvedNameRef.__init__(self, name, ref, expr, is_global) - self.parameter = parameter self.location = location def access_location(self): @@ -115,7 +114,7 @@ # All other assignments involve the names as they were given. else: - return "(%s%s) = %s" % (self.parameter and "*" or "", attrname, self.expr) + return "%s = %s" % (attrname, self.expr) # Expressions. @@ -133,14 +132,20 @@ # All other accesses involve the names as they were given. else: - return "(%s%s)" % (self.parameter and "*" or "", attrname) + return "(%s)" % attrname class TrConstantValueRef(ConstantValueRef): "A constant value reference in the translation." def __str__(self): - return encode_literal_constant(self.number) + + # NOTE: Should reference a common variable for the type name. + + if self.ref.get_origin() == "__builtins__.int.int": + return "__INTVALUE(%s)" % self.value + else: + return encode_literal_constant(self.number) class TrLiteralSequenceRef(LiteralSequenceRef):