# HG changeset patch # User Paul Boddie # Date 1488842898 -3600 # Node ID 6a264fb5a3670d91f52d63219c9ff6ca38c86ab9 # Parent 8cae5848b19164c298543350a2ac12867563a929 Switched to using normal, named function parameters instead of arrays. This requires a special function to convert any array-based arguments to the positioned arguments. However, parameters no longer need to be dereferenced when used in functions. Specialised macros are required to invoke functions with different numbers of parameters. Fortunately, the macros required can be deduced from the functions defined in the program. diff -r 8cae5848b191 -r 6a264fb5a367 generator.py --- a/generator.py Mon Mar 06 22:29:36 2017 +0100 +++ b/generator.py Tue Mar 07 00:28:18 2017 +0100 @@ -154,6 +154,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 +195,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 +312,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 +352,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) @@ -398,6 +412,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 +474,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): @@ -1126,6 +1182,8 @@ """ parameters = self.importer.function_parameters[init_ref.get_origin()] + initialiser = init_ref.get_origin() + argmin, argmax = self.get_argument_limits(initialiser) print >>f_code, """\ __attr %s(__attr __args[]) @@ -1134,7 +1192,7 @@ __args[0] = __NEWINSTANCE(%s); /* Call the initialiser. */ - %s(__args); + %s(%s, __args); /* Return the allocated object details. */ return __args[0]; @@ -1142,7 +1200,8 @@ """ % ( encode_instantiator_pointer(path), encode_path(path), - encode_function_pointer(init_ref.get_origin()) + "__CALL%d" % argmax, + encode_function_pointer(initialiser) ) print >>f_signatures, "#define __HAVE_%s" % encode_path(path) @@ -1217,7 +1276,7 @@ fprintf(stderr, "Program terminated due to exception: %%s.\\n", __load_via_object( - %s(__ARGS(__NULL, __tmp_exc.arg)).value, + %s(__NULL, __tmp_exc.arg).value, __data__).strvalue); return 1; } diff -r 8cae5848b191 -r 6a264fb5a367 templates/Makefile --- a/templates/Makefile Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/Makefile Tue Mar 07 00:28:18 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 -O2 LDFLAGS += -lm -lgc diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/buffer.c --- a/templates/native/buffer.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/buffer.c Tue Mar 07 00:28:18 2017 +0100 @@ -26,11 +26,10 @@ #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; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/buffer.h --- a/templates/native/buffer.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/buffer.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/common.c --- a/templates/native/common.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/common.c Tue Mar 07 00:28:18 2017 +0100 @@ -52,7 +52,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 +68,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 8cae5848b191 -r 6a264fb5a367 templates/native/common.h --- a/templates/native/common.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/common.h Tue Mar 07 00:28:18 2017 +0100 @@ -26,6 +26,6 @@ __attr __new_int(int i); __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 8cae5848b191 -r 6a264fb5a367 templates/native/iconv.c --- a/templates/native/iconv.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/iconv.c Tue Mar 07 00:28:18 2017 +0100 @@ -50,14 +50,12 @@ /* 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(state.value, __data__).seqvalue; /* Obtain the string, start position, and remaining bytes from the state. */ @@ -123,11 +121,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 +134,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(tocode.value, __data__).strvalue; /* fromcode.__data__ interpreted as string */ - char *f = __load_via_object(fromcode->value, __data__).strvalue; + char *f = __load_via_object(fromcode.value, __data__).strvalue; iconv_t result; __attr attr; @@ -160,11 +155,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 8cae5848b191 -r 6a264fb5a367 templates/native/iconv.h --- a/templates/native/iconv.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/iconv.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/identity.c --- a/templates/native/identity.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/identity.c Tue Mar 07 00:28:18 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,14 @@ /* 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]; - - 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]; - - 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 8cae5848b191 -r 6a264fb5a367 templates/native/identity.h --- a/templates/native/identity.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/identity.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/int.c --- a/templates/native/int.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/int.c Tue Mar 07 00:28:18 2017 +0100 @@ -32,20 +32,16 @@ /* Integer operations. */ -__attr __fn_native_int_int_new(__attr __args[]) +__attr __fn_native_int_int_new(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - - return __new_int(_data->intvalue); + return __new_int(_data.intvalue); } -__attr __fn_native_int_int_add(__attr __args[]) +__attr __fn_native_int_int_add(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data__ */ + int i = _data.intvalue; + int j = other.intvalue; /* Test for overflow. */ if (((i > 0) && (j > 0) && (i > INT_MAX - j)) || @@ -57,13 +53,11 @@ return __new_int(i + j); } -__attr __fn_native_int_int_sub(__attr __args[]) +__attr __fn_native_int_int_sub(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data__ */ + int i = _data.intvalue; + int j = other.intvalue; /* Test for overflow. */ if (((i < 0) && (j > 0) && (i < INT_MIN + j)) || @@ -75,13 +69,11 @@ return __new_int(i - j); } -__attr __fn_native_int_int_mul(__attr __args[]) +__attr __fn_native_int_int_mul(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data__ */ + int i = _data.intvalue; + int j = other.intvalue; /* Test for overflow. */ if (((i > 0) && (j > 0) && (i > INT_MAX / j)) || @@ -95,13 +87,11 @@ return __new_int(i * j); } -__attr __fn_native_int_int_div(__attr __args[]) +__attr __fn_native_int_int_div(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data__ */ + int i = _data.intvalue; + int j = other.intvalue; /* Test for division by zero or overflow. */ if (j == 0) @@ -113,13 +103,11 @@ return __new_int(i / j); } -__attr __fn_native_int_int_mod(__attr __args[]) +__attr __fn_native_int_int_mod(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* Test for division by zero or overflow. */ if (j == 0) @@ -131,11 +119,10 @@ return __new_int(i % j); } -__attr __fn_native_int_int_neg(__attr __args[]) +__attr __fn_native_int_int_neg(__attr __self, __attr _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* _data interpreted as int.__data_ */ + int i = _data.intvalue; /* Test for overflow. */ if (i == INT_MIN) @@ -145,13 +132,11 @@ return __new_int(-i); } -__attr __fn_native_int_int_pow(__attr __args[]) +__attr __fn_native_int_int_pow(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; int k; errno = 0; @@ -166,108 +151,92 @@ return __new_int(k); } -__attr __fn_native_int_int_and(__attr __args[]) +__attr __fn_native_int_int_and(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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 _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* _data interpreted as int.__data_ */ + int i = _data.intvalue; /* 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 _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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 _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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_lt(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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_gt(__attr __self, __attr _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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 _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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 _data, __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; + /* _data and other interpreted as int.__data_ */ + int i = _data.intvalue; + int j = other.intvalue; /* 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 _data) { - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; + /* _data interpreted as int.__data_ */ + int i = _data.intvalue; /* 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; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/int.h --- a/templates/native/int.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/int.h Tue Mar 07 00:28:18 2017 +0100 @@ -23,32 +23,27 @@ /* Integer operations. */ -__attr __fn_native_int_int_new(__attr __args[]); +__attr __fn_native_int_int_new(__attr __self, __attr _data); -__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_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_lt(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_eq(__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 8cae5848b191 -r 6a264fb5a367 templates/native/introspection.c --- a/templates/native/introspection.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/introspection.c Tue Mar 07 00:28:18 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(name.value, __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); + out = __check_and_load_via_object_null(obj.value, key.pos, key.code); if (out.value == 0) { /* Inspect the object's class if this failed. */ - out = __check_and_load_via_class__(obj->value, key.pos, key.code); + out = __check_and_load_via_class__(obj.value, key.pos, key.code); if (out.value == 0) - return *_default; + return _default; /* Update the context to the object if it is a method. */ - return __update_context(obj->value, out); + return __update_context(obj.value, 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(obj.value, 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(obj.value, cls)) return __builtins___boolean_True; else return __builtins___boolean_False; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/introspection.h --- a/templates/native/introspection.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/introspection.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/io.c --- a/templates/native/io.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/io.c Tue Mar 07 00:28:18 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; - /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __data__).strvalue; + /* filename interpreted as string */ + char *fn = __load_via_object(filename.value, __data__).strvalue; + /* mode interpreted as string */ + char *s = __load_via_object(mode.value, __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; - /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __data__).strvalue; + /* fd interpreted as int */ + int i = __load_via_object(fd.value, __data__).intvalue; + /* mode interpreted as string */ + char *s = __load_via_object(mode.value, __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 = __load_via_object(size.value, __data__).intvalue; char buf[to_read]; size_t have_read; int error; @@ -151,15 +143,12 @@ 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; - /* str.__data__ interpreted as string */ - char *s = __load_via_object(str->value, __data__).strvalue; - /* str.__size__ interpreted as int */ + FILE *f = (FILE *) fp.datavalue; + /* str interpreted as string */ + char *s = __load_via_object(str.value, __data__).strvalue; int to_write = __load_via_object(str->value, __size__).intvalue; size_t have_written = fwrite(s, sizeof(char), to_write, f); int error; @@ -175,11 +164,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 = __load_via_object(fd.value, __data__).intvalue; errno = 0; if (close(i) == -1) @@ -188,14 +176,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 = __load_via_object(fd.value, __data__).intvalue; + /* n interpreted as int */ + int to_read = __load_via_object(n.value, __data__).intvalue; char buf[to_read]; ssize_t have_read; char *s; @@ -213,16 +199,13 @@ 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; - /* str.__data__ interpreted as string */ - char *s = __load_via_object(str->value, __data__).strvalue; - /* str.__size__ interpreted as int */ - int size = __load_via_object(str->value, __size__).intvalue; + /* fd interpreted as int */ + int i = __load_via_object(fd.value, __data__).intvalue; + /* str interpreted as string */ + char *s = __load_via_object(str.value, __data__).strvalue; + int size = __load_via_object(str.value, __size__).intvalue; ssize_t have_written; errno = 0; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/io.h --- a/templates/native/io.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/io.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/limits.c --- a/templates/native/limits.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/limits.c Tue Mar 07 00:28:18 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 @@ -28,12 +28,12 @@ /* Limit definition. */ -__attr __fn_native_limits_get_maxint(__attr __args[]) +__attr __fn_native_limits_get_maxint(__attr __self) { return __new_int(INT_MAX); } -__attr __fn_native_limits_get_minint(__attr __args[]) +__attr __fn_native_limits_get_minint(__attr __self) { return __new_int(INT_MIN); } diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/limits.h --- a/templates/native/limits.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/limits.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/list.c --- a/templates/native/list.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/list.c Tue Mar 07 00:28:18 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 = __load_via_object(size.value, __data__).intvalue; __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 = __load_via_object(size.value, __data__).intvalue; 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; + /* self interpreted as list */ + __fragment *data = __load_via_object(self.value, __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(self.value, __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(self.value, __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(self.value, __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 = __load_via_object(index.value, __data__).intvalue; 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 = __load_via_object(index.value, __data__).intvalue; /* Set the element. */ - elements[i] = *value; + elements[i] = value; return __builtins___none_None; } diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/list.h --- a/templates/native/list.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/list.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/locale.c --- a/templates/native/locale.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/locale.c Tue Mar 07 00:28:18 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 = __load_via_object(category.value, __data__).intvalue; 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 = __load_via_object(category.value, __data__).intvalue; + /* value interpreted as string */ + char *s = __load_via_object(value.value, __data__).strvalue; char *result, *out; size_t length; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/locale.h --- a/templates/native/locale.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/locale.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/program.c --- a/templates/native/program.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/program.c Tue Mar 07 00:28:18 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->value, *callable); + return __test_context(instance.value, callable); } /* Module initialisation. */ diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/program.h --- a/templates/native/program.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/program.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/str.c --- a/templates/native/str.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/str.c Tue Mar 07 00:28:18 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.__data__ */ + int ss = _size.intvalue, os = othersize.intvalue; 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.__data__ */ + int n = _data.intvalue; 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 = __load_via_object(start.value, __data__).intvalue; + /* end interpreted as int */ + int iend = __load_via_object(end.value, __data__).intvalue; + /* step interpreted as int */ + int istep = __load_via_object(step.value, __data__).intvalue; /* Calculate the size of the substring. */ size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/str.h --- a/templates/native/str.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/str.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/system.c --- a/templates/native/system.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/system.c Tue Mar 07 00:28:18 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(__load_via_object(status.value, __data__).intvalue); 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 8cae5848b191 -r 6a264fb5a367 templates/native/system.h --- a/templates/native/system.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/system.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/native/unicode.c --- a/templates/native/unicode.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/unicode.c Tue Mar 07 00:28:18 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; - /* _size interpreted as int */ - int size = _size->intvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue; + /* _size interpreted as int.__data__ */ + int size = _size.intvalue; 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; - /* _size interpreted as int */ - int size = _size->intvalue; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue; + /* _size interpreted as int.__data__ */ + int size = _size.intvalue; 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; - /* _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; + /* _data interpreted as string.__data__ */ + char *s = _data.strvalue, *sub; + /* _size interpreted as int.__data__ */ + int ss = _size.intvalue; + /* start interpreted as int */ + int istart = __load_via_object(start.value, __data__).intvalue; + /* end interpreted as int */ + int iend = __load_via_object(end.value, __data__).intvalue; + /* step interpreted as int */ + int istep = __load_via_object(step.value, __data__).intvalue; /* 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; + /* value interpreted as int.__data__ */ + int i = value.intvalue; unsigned int resultsize; char *s; diff -r 8cae5848b191 -r 6a264fb5a367 templates/native/unicode.h --- a/templates/native/unicode.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/native/unicode.h Tue Mar 07 00:28:18 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 8cae5848b191 -r 6a264fb5a367 templates/ops.c --- a/templates/ops.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/ops.c Tue Mar 07 00:28:18 2017 +0100 @@ -308,7 +308,7 @@ return value.value ? value : callable; } -__attr (*__get_function(__ref context, __attr target))(__attr[]) +__attr (*__get_function(__ref context, __attr target))() { target = __unwrap_callable(target); @@ -321,7 +321,7 @@ return __unbound_method; } -__attr (*__check_and_get_function(__ref context, __attr target))(__attr[]) +__attr (*__check_and_get_function(__ref context, __attr target))() { target = __unwrap_callable(target); diff -r 8cae5848b191 -r 6a264fb5a367 templates/ops.h --- a/templates/ops.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/ops.h Tue Mar 07 00:28:18 2017 +0100 @@ -108,8 +108,8 @@ /* Context testing for invocations. */ __attr __unwrap_callable(__attr callable); -__attr (*__get_function(__ref context, __attr target))(__attr[]); -__attr (*__check_and_get_function(__ref context, __attr target))(__attr[]); +__attr (*__get_function(__ref context, __attr target))(); +__attr (*__check_and_get_function(__ref context, __attr target))(); /* Parameter position operations. */ diff -r 8cae5848b191 -r 6a264fb5a367 templates/progops.c --- a/templates/progops.c Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/progops.c Tue Mar 07 00:28:18 2017 +0100 @@ -24,6 +24,7 @@ #include "progtypes.h" #include "main.h" #include "exceptions.h" +#include "calls.h" /* Generic instantiation operations, defining common members. */ @@ -251,14 +252,19 @@ } } - /* 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(allargs[0].value, target) : __check_and_get_function(allargs[0].value, target))(allargs); + return __call_with_args( + always_callable ? + __get_function(allargs[0].value, target) : + __check_and_get_function(allargs[0].value, 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); @@ -280,10 +286,8 @@ int __BOOL(__attr attr) { - __attr args[2] = {__NULL, attr}; - /* Invoke the bool function with the object and test against True. */ return (attr.value == __builtins___boolean_True.value) || - (__fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value); + (__fn___builtins___boolean_bool(__NULL, attr).value == __builtins___boolean_True.value); } diff -r 8cae5848b191 -r 6a264fb5a367 templates/progops.h --- a/templates/progops.h Mon Mar 06 22:29:36 2017 +0100 +++ b/templates/progops.h Tue Mar 07 00:28:18 2017 +0100 @@ -60,12 +60,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. */ @@ -78,6 +78,6 @@ /* Convenience definitions. */ #define __NEWINSTANCE(__CLS) __new(&__InstanceTable_##__CLS, &__CLS, sizeof(__obj_##__CLS)) -#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 8cae5848b191 -r 6a264fb5a367 translator.py --- a/translator.py Mon Mar 06 22:29:36 2017 +0100 +++ b/translator.py Tue Mar 07 00:28:18 2017 +0100 @@ -848,10 +848,7 @@ # Produce an appropriate access to an attribute's value. parameters = self.importer.function_parameters.get(self.get_namespace_path()) - if parameters and name in parameters: - name_to_value = "%s->value" % name - else: - name_to_value = "%s.value" % name + name_to_value = "%s.value" % name # Write a test that raises a TypeError upon failure. @@ -1187,7 +1184,7 @@ # Encode the arguments. - argstr = "__ARGS(%s)" % ", ".join(args) + argstr = ", ".join(args) kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0" kwcodestr = kwcodes and ("__KWARGS(%s)" % ", ".join(kwcodes)) or "0" @@ -1195,7 +1192,9 @@ # the number of values. if literal_instantiation: - argstr += ", %d" % (len(args) - 1) + argstr = "__ARGS(%s), %d" % (argstr, len(args) - 1) + elif instantiation: + argstr = "__ARGS(%s)" % argstr # First, the invocation expression is presented. @@ -1249,7 +1248,7 @@ target_var, self.always_callable and 1 or 0, len(kwargs), kwcodestr, kwargstr, - len(args), argstr)) + len(args), "__ARGS(%s)" % argstr)) return InvocationResult(stages) def always_callable(self, refs): @@ -1390,7 +1389,7 @@ # static namespace members. The reference should be configured to return # such names. - return TrResolvedNameRef(n.name, ref, expr=expr, is_global=is_global, parameter=parameter, location=location) + return TrResolvedNameRef(n.name, ref, expr=expr, is_global=is_global, location=location) def process_not_node(self, n): @@ -1761,7 +1760,8 @@ "Start the function having the given 'name'." - print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name) + self.write_parameters(name) + print >>self.out, "{" self.indent += 1 @@ -1787,7 +1787,6 @@ names.sort() self.writeline("__attr %s;" % ", ".join(names)) - self.write_parameters(name) self.start_unit() def end_function(self, name): @@ -1797,6 +1796,30 @@ self.end_unit(name) 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("__attr %s" % 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'." @@ -1826,25 +1849,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("__attr * const %s = &__args[%d];" % (encode_path(parameter), i+1)) - def start_if(self, first, test_ref): statement = "%sif" % (not first and "else " or "") diff -r 8cae5848b191 -r 6a264fb5a367 transresults.py --- a/transresults.py Mon Mar 06 22:29:36 2017 +0100 +++ b/transresults.py Tue Mar 07 00:28:18 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): @@ -107,7 +106,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. @@ -125,7 +124,7 @@ # 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):