Lichen

Changeset

664:6a264fb5a367
2017-03-07 Paul Boddie raw files shortlog changelog graph 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. normal-function-parameters
generator.py (file) templates/Makefile (file) templates/native/buffer.c (file) templates/native/buffer.h (file) templates/native/common.c (file) templates/native/common.h (file) templates/native/iconv.c (file) templates/native/iconv.h (file) templates/native/identity.c (file) templates/native/identity.h (file) templates/native/int.c (file) templates/native/int.h (file) templates/native/introspection.c (file) templates/native/introspection.h (file) templates/native/io.c (file) templates/native/io.h (file) templates/native/limits.c (file) templates/native/limits.h (file) templates/native/list.c (file) templates/native/list.h (file) templates/native/locale.c (file) templates/native/locale.h (file) templates/native/program.c (file) templates/native/program.h (file) templates/native/str.c (file) templates/native/str.h (file) templates/native/system.c (file) templates/native/system.h (file) templates/native/unicode.c (file) templates/native/unicode.h (file) templates/ops.c (file) templates/ops.h (file) templates/progops.c (file) templates/progops.h (file) translator.py (file) transresults.py (file)
     1.1 --- a/generator.py	Mon Mar 06 22:29:36 2017 +0100
     1.2 +++ b/generator.py	Tue Mar 07 00:28:18 2017 +0100
     1.3 @@ -154,6 +154,8 @@
     1.4          f_decls = open(join(self.output, "progtypes.h"), "w")
     1.5          f_signatures = open(join(self.output, "main.h"), "w")
     1.6          f_code = open(join(self.output, "main.c"), "w")
     1.7 +        f_calls = open(join(self.output, "calls.c"), "w")
     1.8 +        f_call_macros = open(join(self.output, "calls.h"), "w")
     1.9  
    1.10          try:
    1.11              # Output boilerplate.
    1.12 @@ -193,6 +195,14 @@
    1.13  #include "progtypes.h"
    1.14  #include "main.h"
    1.15  #include "progops.h"
    1.16 +#include "calls.h"
    1.17 +"""
    1.18 +
    1.19 +            print >>f_call_macros, """\
    1.20 +#ifndef __CALLS_H__
    1.21 +#define __CALLS_H__
    1.22 +
    1.23 +#include "types.h"
    1.24  """
    1.25  
    1.26              # Generate table and structure data.
    1.27 @@ -302,15 +312,18 @@
    1.28                      extra_function_instances.append(path)
    1.29  
    1.30                  # Write function declarations.
    1.31 -                # Signature: __attr <name>(__attr[]);
    1.32 +                # Signature: __attr <name>(...);
    1.33  
    1.34 -                print >>f_signatures, "__attr %s(__attr args[]);" % encode_function_pointer(path)
    1.35 +                parameters = self.importer.function_parameters[path]
    1.36 +                l = ["__attr"] * (len(parameters) + 1)
    1.37 +                print >>f_signatures, "__attr %s(%s);" % (encode_function_pointer(path), ", ".join(l))
    1.38  
    1.39              # Generate parameter table size data.
    1.40  
    1.41              min_parameters = {}
    1.42              max_parameters = {}
    1.43              size_parameters = {}
    1.44 +            all_max_parameters = set()
    1.45  
    1.46              # Consolidate parameter tables for instantiators and functions.
    1.47  
    1.48 @@ -339,6 +352,7 @@
    1.49                  min_parameters[signature] = argmin
    1.50                  max_parameters[signature] = argmax
    1.51                  size_parameters[signature] = len(parameters)
    1.52 +                all_max_parameters.add(argmax)
    1.53  
    1.54              self.write_size_constants(f_consts, "pmin", min_parameters, 0)
    1.55              self.write_size_constants(f_consts, "pmax", max_parameters, 0)
    1.56 @@ -398,6 +412,42 @@
    1.57                                        self.optimiser.locations,
    1.58                                        "code", "pos", encode_code, encode_pos)
    1.59  
    1.60 +            # Generate macros for calls.
    1.61 +
    1.62 +            all_max_parameters = list(all_max_parameters)
    1.63 +            all_max_parameters.sort()
    1.64 +
    1.65 +            for argmax in all_max_parameters:
    1.66 +                l = []
    1.67 +                argnum = 0
    1.68 +                while argnum < argmax:
    1.69 +                    l.append("ARGS[%d]" % argnum)
    1.70 +                    argnum += 1
    1.71 +
    1.72 +                print >>f_call_macros, "#define __CALL%d(FN, ARGS) (FN(%s))" % (argmax, ", ".join(l))
    1.73 +
    1.74 +            # Generate a generic invocation function.
    1.75 +
    1.76 +            print >>f_call_macros, "__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n);"
    1.77 +
    1.78 +            print >>f_calls, """\
    1.79 +#include "types.h"
    1.80 +#include "calls.h"
    1.81 +
    1.82 +__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n)
    1.83 +{
    1.84 +    switch (n)
    1.85 +    {"""
    1.86 +
    1.87 +            for argmax in all_max_parameters:
    1.88 +                print >>f_calls, """\
    1.89 +        case %d: return __CALL%d(fn, args);""" % (argmax, argmax)
    1.90 +
    1.91 +            print >>f_calls, """\
    1.92 +        default: return __NULL;
    1.93 +    }
    1.94 +}"""
    1.95 +
    1.96              # Output more boilerplate.
    1.97  
    1.98              print >>f_consts, """\
    1.99 @@ -424,12 +474,18 @@
   1.100  
   1.101  #endif /* __MAIN_H__ */"""
   1.102  
   1.103 +            print >>f_call_macros, """\
   1.104 +
   1.105 +#endif /* __CALLS_H__ */"""
   1.106 +
   1.107          finally:
   1.108              f_consts.close()
   1.109              f_defs.close()
   1.110              f_decls.close()
   1.111              f_signatures.close()
   1.112              f_code.close()
   1.113 +            f_calls.close()
   1.114 +            f_call_macros.close()
   1.115  
   1.116      def write_scripts(self, debug, gc_sections):
   1.117  
   1.118 @@ -1126,6 +1182,8 @@
   1.119          """
   1.120  
   1.121          parameters = self.importer.function_parameters[init_ref.get_origin()]
   1.122 +        initialiser = init_ref.get_origin()
   1.123 +        argmin, argmax = self.get_argument_limits(initialiser)
   1.124  
   1.125          print >>f_code, """\
   1.126  __attr %s(__attr __args[])
   1.127 @@ -1134,7 +1192,7 @@
   1.128      __args[0] = __NEWINSTANCE(%s);
   1.129  
   1.130      /* Call the initialiser. */
   1.131 -    %s(__args);
   1.132 +    %s(%s, __args);
   1.133  
   1.134      /* Return the allocated object details. */
   1.135      return __args[0];
   1.136 @@ -1142,7 +1200,8 @@
   1.137  """ % (
   1.138      encode_instantiator_pointer(path),
   1.139      encode_path(path),
   1.140 -    encode_function_pointer(init_ref.get_origin())
   1.141 +    "__CALL%d" % argmax,
   1.142 +    encode_function_pointer(initialiser)
   1.143      )
   1.144  
   1.145          print >>f_signatures, "#define __HAVE_%s" % encode_path(path)
   1.146 @@ -1217,7 +1276,7 @@
   1.147  
   1.148          fprintf(stderr, "Program terminated due to exception: %%s.\\n",
   1.149                  __load_via_object(
   1.150 -                    %s(__ARGS(__NULL, __tmp_exc.arg)).value,
   1.151 +                    %s(__NULL, __tmp_exc.arg).value,
   1.152                      __data__).strvalue);
   1.153          return 1;
   1.154      }
     2.1 --- a/templates/Makefile	Mon Mar 06 22:29:36 2017 +0100
     2.2 +++ b/templates/Makefile	Tue Mar 07 00:28:18 2017 +0100
     2.3 @@ -2,7 +2,7 @@
     2.4  include modules.mk
     2.5  include options.mk
     2.6  
     2.7 -SRC += exceptions.c main.c ops.c progops.c progtypes.c
     2.8 +SRC += calls.c exceptions.c main.c ops.c progops.c progtypes.c
     2.9  OBJ = $(SRC:.c=.o)
    2.10  CFLAGS += -Wall -I. -finput-charset=UTF-8 -O2
    2.11  LDFLAGS += -lm -lgc
     3.1 --- a/templates/native/buffer.c	Mon Mar 06 22:29:36 2017 +0100
     3.2 +++ b/templates/native/buffer.c	Tue Mar 07 00:28:18 2017 +0100
     3.3 @@ -26,11 +26,10 @@
     3.4  #include "progtypes.h"
     3.5  #include "main.h"
     3.6  
     3.7 -__attr __fn_native_buffer_buffer_str(__attr __args[])
     3.8 +__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data)
     3.9  {
    3.10 -    __attr * const _data = &__args[1];
    3.11 -    /* _data interpreted as buffer */
    3.12 -    __fragment *data = _data->seqvalue;
    3.13 +    /* _data interpreted as buffer.__data__ */
    3.14 +    __fragment *data = _data.seqvalue;
    3.15      unsigned int size = 0, i, j, n;
    3.16      char *s;
    3.17      __attr o;
     4.1 --- a/templates/native/buffer.h	Mon Mar 06 22:29:36 2017 +0100
     4.2 +++ b/templates/native/buffer.h	Tue Mar 07 00:28:18 2017 +0100
     4.3 @@ -1,6 +1,6 @@
     4.4  /* Native functions for buffer operations.
     4.5  
     4.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
     4.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     4.8  
     4.9  This program is free software; you can redistribute it and/or modify it under
    4.10  the terms of the GNU General Public License as published by the Free Software
    4.11 @@ -23,7 +23,7 @@
    4.12  
    4.13  /* Buffer operations. */
    4.14  
    4.15 -__attr __fn_native_buffer_buffer_str(__attr __args[]);
    4.16 +__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data);
    4.17  
    4.18  /* Module initialisation. */
    4.19  
     5.1 --- a/templates/native/common.c	Mon Mar 06 22:29:36 2017 +0100
     5.2 +++ b/templates/native/common.c	Tue Mar 07 00:28:18 2017 +0100
     5.3 @@ -52,7 +52,7 @@
     5.4      return attr;
     5.5  }
     5.6  
     5.7 -__fragment *__fragment_append(__fragment *data, __attr * const value)
     5.8 +__fragment *__fragment_append(__fragment *data, __attr value)
     5.9  {
    5.10      __fragment *newdata = data;
    5.11      unsigned int size = data->size, capacity = data->capacity;
    5.12 @@ -68,7 +68,7 @@
    5.13      }
    5.14  
    5.15      /* Insert the new element and increment the list size. */
    5.16 -    newdata->attrs[size] = *value;
    5.17 +    newdata->attrs[size] = value;
    5.18      newdata->size = size + 1;
    5.19  
    5.20      return newdata;
     6.1 --- a/templates/native/common.h	Mon Mar 06 22:29:36 2017 +0100
     6.2 +++ b/templates/native/common.h	Tue Mar 07 00:28:18 2017 +0100
     6.3 @@ -26,6 +26,6 @@
     6.4  __attr __new_int(int i);
     6.5  __attr __new_str(char *s, int size);
     6.6  __attr __new_list(__fragment *f);
     6.7 -__fragment *__fragment_append(__fragment *data, __attr * const value);
     6.8 +__fragment *__fragment_append(__fragment *data, __attr value);
     6.9  
    6.10  #endif /* __NATIVE_COMMON_H__ */
     7.1 --- a/templates/native/iconv.c	Mon Mar 06 22:29:36 2017 +0100
     7.2 +++ b/templates/native/iconv.c	Tue Mar 07 00:28:18 2017 +0100
     7.3 @@ -50,14 +50,12 @@
     7.4  
     7.5  /* Character set conversion. */
     7.6  
     7.7 -__attr __fn_native_iconv_iconv(__attr __args[])
     7.8 +__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state)
     7.9  {
    7.10 -    __attr * const cd = &__args[1];
    7.11 -    __attr * const state = &__args[2];
    7.12      /* cd interpreted as iconv_t */
    7.13 -    iconv_t c = (iconv_t) cd->datavalue;
    7.14 +    iconv_t c = (iconv_t) cd.datavalue;
    7.15      /* state.__data__ interpreted as list */
    7.16 -    __fragment *f = __load_via_object(state->value, __data__).seqvalue;
    7.17 +    __fragment *f = __load_via_object(state.value, __data__).seqvalue;
    7.18  
    7.19      /* Obtain the string, start position, and remaining bytes from the state. */
    7.20  
    7.21 @@ -123,11 +121,10 @@
    7.22      return __builtins___none_None;
    7.23  }
    7.24  
    7.25 -__attr __fn_native_iconv_iconv_close(__attr __args[])
    7.26 +__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd)
    7.27  {
    7.28 -    __attr * const cd = &__args[1];
    7.29      /* cd interpreted as iconv_t */
    7.30 -    iconv_t c = (iconv_t) cd->datavalue;
    7.31 +    iconv_t c = (iconv_t) cd.datavalue;
    7.32  
    7.33      errno = 0;
    7.34  
    7.35 @@ -137,14 +134,12 @@
    7.36      return __builtins___none_None;
    7.37  }
    7.38  
    7.39 -__attr __fn_native_iconv_iconv_open(__attr __args[])
    7.40 +__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode)
    7.41  {
    7.42 -    __attr * const tocode = &__args[1];
    7.43 -    __attr * const fromcode = &__args[2];
    7.44      /* tocode.__data__ interpreted as string */
    7.45 -    char *t = __load_via_object(tocode->value, __data__).strvalue;
    7.46 +    char *t = __load_via_object(tocode.value, __data__).strvalue;
    7.47      /* fromcode.__data__ interpreted as string */
    7.48 -    char *f = __load_via_object(fromcode->value, __data__).strvalue;
    7.49 +    char *f = __load_via_object(fromcode.value, __data__).strvalue;
    7.50      iconv_t result;
    7.51      __attr attr;
    7.52  
    7.53 @@ -160,11 +155,10 @@
    7.54      return attr;
    7.55  }
    7.56  
    7.57 -__attr __fn_native_iconv_iconv_reset(__attr __args[])
    7.58 +__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd)
    7.59  {
    7.60 -    __attr * const cd = &__args[1];
    7.61      /* cd interpreted as iconv_t */
    7.62 -    iconv_t c = (iconv_t) cd->datavalue;
    7.63 +    iconv_t c = (iconv_t) cd.datavalue;
    7.64  
    7.65      iconv(c, NULL, NULL, NULL, NULL);
    7.66      return __builtins___none_None;
     8.1 --- a/templates/native/iconv.h	Mon Mar 06 22:29:36 2017 +0100
     8.2 +++ b/templates/native/iconv.h	Tue Mar 07 00:28:18 2017 +0100
     8.3 @@ -1,6 +1,6 @@
     8.4  /* Native functions for character set conversion.
     8.5  
     8.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
     8.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     8.8  
     8.9  This program is free software; you can redistribute it and/or modify it under
    8.10  the terms of the GNU General Public License as published by the Free Software
    8.11 @@ -23,10 +23,10 @@
    8.12  
    8.13  /* Input/output. */
    8.14  
    8.15 -__attr __fn_native_iconv_iconv(__attr __args[]);
    8.16 -__attr __fn_native_iconv_iconv_close(__attr __args[]);
    8.17 -__attr __fn_native_iconv_iconv_open(__attr __args[]);
    8.18 -__attr __fn_native_iconv_iconv_reset(__attr __args[]);
    8.19 +__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state);
    8.20 +__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd);
    8.21 +__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode);
    8.22 +__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd);
    8.23  
    8.24  /* Module initialisation. */
    8.25  
     9.1 --- a/templates/native/identity.c	Mon Mar 06 22:29:36 2017 +0100
     9.2 +++ b/templates/native/identity.c	Tue Mar 07 00:28:18 2017 +0100
     9.3 @@ -1,6 +1,6 @@
     9.4  /* Native functions for identity operations.
     9.5  
     9.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
     9.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     9.8  
     9.9  This program is free software; you can redistribute it and/or modify it under
    9.10  the terms of the GNU General Public License as published by the Free Software
    9.11 @@ -26,20 +26,14 @@
    9.12  
    9.13  /* Identity testing. */
    9.14  
    9.15 -__attr __fn_native_identity_is_(__attr __args[])
    9.16 +__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y)
    9.17  {
    9.18 -    __attr * const x = &__args[1];
    9.19 -    __attr * const y = &__args[2];
    9.20 -
    9.21 -    return x->value == y->value ? __builtins___boolean_True : __builtins___boolean_False;
    9.22 +    return x.value == y.value ? __builtins___boolean_True : __builtins___boolean_False;
    9.23  }
    9.24  
    9.25 -__attr __fn_native_identity_is_not(__attr __args[])
    9.26 +__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y)
    9.27  {
    9.28 -    __attr * const x = &__args[1];
    9.29 -    __attr * const y = &__args[2];
    9.30 -
    9.31 -    return x->value != y->value ? __builtins___boolean_True : __builtins___boolean_False;
    9.32 +    return x.value != y.value ? __builtins___boolean_True : __builtins___boolean_False;
    9.33  }
    9.34  
    9.35  /* Module initialisation. */
    10.1 --- a/templates/native/identity.h	Mon Mar 06 22:29:36 2017 +0100
    10.2 +++ b/templates/native/identity.h	Tue Mar 07 00:28:18 2017 +0100
    10.3 @@ -1,6 +1,6 @@
    10.4  /* Native functions for identity operations.
    10.5  
    10.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    10.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    10.8  
    10.9  This program is free software; you can redistribute it and/or modify it under
   10.10  the terms of the GNU General Public License as published by the Free Software
   10.11 @@ -23,8 +23,8 @@
   10.12  
   10.13  /* Identity testing. */
   10.14  
   10.15 -__attr __fn_native_identity_is_(__attr __args[]);
   10.16 -__attr __fn_native_identity_is_not(__attr __args[]);
   10.17 +__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y);
   10.18 +__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y);
   10.19  
   10.20  /* Module initialisation. */
   10.21  
    11.1 --- a/templates/native/int.c	Mon Mar 06 22:29:36 2017 +0100
    11.2 +++ b/templates/native/int.c	Tue Mar 07 00:28:18 2017 +0100
    11.3 @@ -32,20 +32,16 @@
    11.4  
    11.5  /* Integer operations. */
    11.6  
    11.7 -__attr __fn_native_int_int_new(__attr __args[])
    11.8 +__attr __fn_native_int_int_new(__attr __self, __attr _data)
    11.9  {
   11.10 -    __attr * const _data = &__args[1];
   11.11 -
   11.12 -    return __new_int(_data->intvalue);
   11.13 +    return __new_int(_data.intvalue);
   11.14  }
   11.15  
   11.16 -__attr __fn_native_int_int_add(__attr __args[])
   11.17 +__attr __fn_native_int_int_add(__attr __self, __attr _data, __attr other)
   11.18  {
   11.19 -    __attr * const _data = &__args[1];
   11.20 -    __attr * const other = &__args[2];
   11.21 -    /* _data and other interpreted as int */
   11.22 -    int i = _data->intvalue;
   11.23 -    int j = other->intvalue;
   11.24 +    /* _data and other interpreted as int.__data__ */
   11.25 +    int i = _data.intvalue;
   11.26 +    int j = other.intvalue;
   11.27  
   11.28      /* Test for overflow. */
   11.29      if (((i > 0) && (j > 0) && (i > INT_MAX - j)) ||
   11.30 @@ -57,13 +53,11 @@
   11.31      return __new_int(i + j);
   11.32  }
   11.33  
   11.34 -__attr __fn_native_int_int_sub(__attr __args[])
   11.35 +__attr __fn_native_int_int_sub(__attr __self, __attr _data, __attr other)
   11.36  {
   11.37 -    __attr * const _data = &__args[1];
   11.38 -    __attr * const other = &__args[2];
   11.39 -    /* _data and other interpreted as int */
   11.40 -    int i = _data->intvalue;
   11.41 -    int j = other->intvalue;
   11.42 +    /* _data and other interpreted as int.__data__ */
   11.43 +    int i = _data.intvalue;
   11.44 +    int j = other.intvalue;
   11.45  
   11.46      /* Test for overflow. */
   11.47      if (((i < 0) && (j > 0) && (i < INT_MIN + j)) ||
   11.48 @@ -75,13 +69,11 @@
   11.49      return __new_int(i - j);
   11.50  }
   11.51  
   11.52 -__attr __fn_native_int_int_mul(__attr __args[])
   11.53 +__attr __fn_native_int_int_mul(__attr __self, __attr _data, __attr other)
   11.54  {
   11.55 -    __attr * const _data = &__args[1];
   11.56 -    __attr * const other = &__args[2];
   11.57 -    /* _data and other interpreted as int */
   11.58 -    int i = _data->intvalue;
   11.59 -    int j = other->intvalue;
   11.60 +    /* _data and other interpreted as int.__data__ */
   11.61 +    int i = _data.intvalue;
   11.62 +    int j = other.intvalue;
   11.63  
   11.64      /* Test for overflow. */
   11.65      if (((i > 0) && (j > 0) && (i > INT_MAX / j)) ||
   11.66 @@ -95,13 +87,11 @@
   11.67      return __new_int(i * j);
   11.68  }
   11.69  
   11.70 -__attr __fn_native_int_int_div(__attr __args[])
   11.71 +__attr __fn_native_int_int_div(__attr __self, __attr _data, __attr other)
   11.72  {
   11.73 -    __attr * const _data = &__args[1];
   11.74 -    __attr * const other = &__args[2];
   11.75 -    /* _data and other interpreted as int */
   11.76 -    int i = _data->intvalue;
   11.77 -    int j = other->intvalue;
   11.78 +    /* _data and other interpreted as int.__data__ */
   11.79 +    int i = _data.intvalue;
   11.80 +    int j = other.intvalue;
   11.81  
   11.82      /* Test for division by zero or overflow. */
   11.83      if (j == 0)
   11.84 @@ -113,13 +103,11 @@
   11.85      return __new_int(i / j);
   11.86  }
   11.87  
   11.88 -__attr __fn_native_int_int_mod(__attr __args[])
   11.89 +__attr __fn_native_int_int_mod(__attr __self, __attr _data, __attr other)
   11.90  {
   11.91 -    __attr * const _data = &__args[1];
   11.92 -    __attr * const other = &__args[2];
   11.93 -    /* _data and other interpreted as int */
   11.94 -    int i = _data->intvalue;
   11.95 -    int j = other->intvalue;
   11.96 +    /* _data and other interpreted as int.__data_ */
   11.97 +    int i = _data.intvalue;
   11.98 +    int j = other.intvalue;
   11.99  
  11.100      /* Test for division by zero or overflow. */
  11.101      if (j == 0)
  11.102 @@ -131,11 +119,10 @@
  11.103      return __new_int(i % j);
  11.104  }
  11.105  
  11.106 -__attr __fn_native_int_int_neg(__attr __args[])
  11.107 +__attr __fn_native_int_int_neg(__attr __self, __attr _data)
  11.108  {
  11.109 -    __attr * const _data = &__args[1];
  11.110 -    /* _data interpreted as int */
  11.111 -    int i = _data->intvalue;
  11.112 +    /* _data interpreted as int.__data_ */
  11.113 +    int i = _data.intvalue;
  11.114  
  11.115      /* Test for overflow. */
  11.116      if (i == INT_MIN)
  11.117 @@ -145,13 +132,11 @@
  11.118      return __new_int(-i);
  11.119  }
  11.120  
  11.121 -__attr __fn_native_int_int_pow(__attr __args[])
  11.122 +__attr __fn_native_int_int_pow(__attr __self, __attr _data, __attr other)
  11.123  {
  11.124 -    __attr * const _data = &__args[1];
  11.125 -    __attr * const other = &__args[2];
  11.126 -    /* _data and other interpreted as int */
  11.127 -    int i = _data->intvalue;
  11.128 -    int j = other->intvalue;
  11.129 +    /* _data and other interpreted as int.__data_ */
  11.130 +    int i = _data.intvalue;
  11.131 +    int j = other.intvalue;
  11.132      int k;
  11.133  
  11.134      errno = 0;
  11.135 @@ -166,108 +151,92 @@
  11.136      return __new_int(k);
  11.137  }
  11.138  
  11.139 -__attr __fn_native_int_int_and(__attr __args[])
  11.140 +__attr __fn_native_int_int_and(__attr __self, __attr _data, __attr other)
  11.141  {
  11.142 -    __attr * const _data = &__args[1];
  11.143 -    __attr * const other = &__args[2];
  11.144 -    /* _data and other interpreted as int */
  11.145 -    int i = _data->intvalue;
  11.146 -    int j = other->intvalue;
  11.147 +    /* _data and other interpreted as int.__data_ */
  11.148 +    int i = _data.intvalue;
  11.149 +    int j = other.intvalue;
  11.150  
  11.151      /* Return the new integer. */
  11.152      /* NOTE: No overflow test applied. */
  11.153      return __new_int(i & j);
  11.154  }
  11.155  
  11.156 -__attr __fn_native_int_int_not(__attr __args[])
  11.157 +__attr __fn_native_int_int_not(__attr __self, __attr _data)
  11.158  {
  11.159 -    __attr * const _data = &__args[1];
  11.160 -    /* _data interpreted as int */
  11.161 -    int i = _data->intvalue;
  11.162 +    /* _data interpreted as int.__data_ */
  11.163 +    int i = _data.intvalue;
  11.164  
  11.165      /* Return the new integer. */
  11.166      return __new_int(~i);
  11.167  }
  11.168  
  11.169 -__attr __fn_native_int_int_or(__attr __args[])
  11.170 +__attr __fn_native_int_int_or(__attr __self, __attr _data, __attr other)
  11.171  {
  11.172 -    __attr * const _data = &__args[1];
  11.173 -    __attr * const other = &__args[2];
  11.174 -    /* _data and other interpreted as int */
  11.175 -    int i = _data->intvalue;
  11.176 -    int j = other->intvalue;
  11.177 +    /* _data and other interpreted as int.__data_ */
  11.178 +    int i = _data.intvalue;
  11.179 +    int j = other.intvalue;
  11.180  
  11.181      /* Return the new integer. */
  11.182      /* NOTE: No overflow test applied. */
  11.183      return __new_int(i | j);
  11.184  }
  11.185  
  11.186 -__attr __fn_native_int_int_xor(__attr __args[])
  11.187 +__attr __fn_native_int_int_xor(__attr __self, __attr _data, __attr other)
  11.188  {
  11.189 -    __attr * const _data = &__args[1];
  11.190 -    __attr * const other = &__args[2];
  11.191 -    /* _data and other interpreted as int */
  11.192 -    int i = _data->intvalue;
  11.193 -    int j = other->intvalue;
  11.194 +    /* _data and other interpreted as int.__data_ */
  11.195 +    int i = _data.intvalue;
  11.196 +    int j = other.intvalue;
  11.197  
  11.198      /* Return the new integer. */
  11.199      /* NOTE: No overflow test applied. */
  11.200      return __new_int(i ^ j);
  11.201  }
  11.202  
  11.203 -__attr __fn_native_int_int_lt(__attr __args[])
  11.204 +__attr __fn_native_int_int_lt(__attr __self, __attr _data, __attr other)
  11.205  {
  11.206 -    __attr * const _data = &__args[1];
  11.207 -    __attr * const other = &__args[2];
  11.208 -    /* _data and other interpreted as int */
  11.209 -    int i = _data->intvalue;
  11.210 -    int j = other->intvalue;
  11.211 +    /* _data and other interpreted as int.__data_ */
  11.212 +    int i = _data.intvalue;
  11.213 +    int j = other.intvalue;
  11.214  
  11.215      /* Return a boolean result. */
  11.216      return i < j ? __builtins___boolean_True : __builtins___boolean_False;
  11.217  }
  11.218  
  11.219 -__attr __fn_native_int_int_gt(__attr __args[])
  11.220 +__attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other)
  11.221  {
  11.222 -    __attr * const _data = &__args[1];
  11.223 -    __attr * const other = &__args[2];
  11.224 -    /* _data and other interpreted as int */
  11.225 -    int i = _data->intvalue;
  11.226 -    int j = other->intvalue;
  11.227 +    /* _data and other interpreted as int.__data_ */
  11.228 +    int i = _data.intvalue;
  11.229 +    int j = other.intvalue;
  11.230  
  11.231      /* Return a boolean result. */
  11.232      return i > j ? __builtins___boolean_True : __builtins___boolean_False;
  11.233  }
  11.234  
  11.235 -__attr __fn_native_int_int_eq(__attr __args[])
  11.236 +__attr __fn_native_int_int_eq(__attr __self, __attr _data, __attr other)
  11.237  {
  11.238 -    __attr * const _data = &__args[1];
  11.239 -    __attr * const other = &__args[2];
  11.240 -    /* _data and other interpreted as int */
  11.241 -    int i = _data->intvalue;
  11.242 -    int j = other->intvalue;
  11.243 +    /* _data and other interpreted as int.__data_ */
  11.244 +    int i = _data.intvalue;
  11.245 +    int j = other.intvalue;
  11.246  
  11.247      /* Return a boolean result. */
  11.248      return i == j ? __builtins___boolean_True : __builtins___boolean_False;
  11.249  }
  11.250  
  11.251 -__attr __fn_native_int_int_ne(__attr __args[])
  11.252 +__attr __fn_native_int_int_ne(__attr __self, __attr _data, __attr other)
  11.253  {
  11.254 -    __attr * const _data = &__args[1];
  11.255 -    __attr * const other = &__args[2];
  11.256 -    /* _data and other interpreted as int */
  11.257 -    int i = _data->intvalue;
  11.258 -    int j = other->intvalue;
  11.259 +    /* _data and other interpreted as int.__data_ */
  11.260 +    int i = _data.intvalue;
  11.261 +    int j = other.intvalue;
  11.262  
  11.263      /* Return a boolean result. */
  11.264      return i != j ? __builtins___boolean_True : __builtins___boolean_False;
  11.265  }
  11.266  
  11.267 -__attr __fn_native_int_int_str(__attr __args[])
  11.268 +__attr __fn_native_int_int_str(__attr __self, __attr _data)
  11.269  {
  11.270 -    __attr * const _data = &__args[1];
  11.271 -    /* _data interpreted as int */
  11.272 -    int i = _data->intvalue;
  11.273 +    /* _data interpreted as int.__data_ */
  11.274 +    int i = _data.intvalue;
  11.275      /* Employ a buffer big enough to fit the largest integer plus an extra
  11.276         character, a minus sign, and the null terminator. */
  11.277      unsigned int n = (int) log10(INT_MAX) + 3;
    12.1 --- a/templates/native/int.h	Mon Mar 06 22:29:36 2017 +0100
    12.2 +++ b/templates/native/int.h	Tue Mar 07 00:28:18 2017 +0100
    12.3 @@ -23,32 +23,27 @@
    12.4  
    12.5  /* Integer operations. */
    12.6  
    12.7 -__attr __fn_native_int_int_new(__attr __args[]);
    12.8 +__attr __fn_native_int_int_new(__attr __self, __attr _data);
    12.9  
   12.10 -__attr __fn_native_int_int_add(__attr __args[]);
   12.11 -__attr __fn_native_int_int_div(__attr __args[]);
   12.12 -__attr __fn_native_int_int_mod(__attr __args[]);
   12.13 -__attr __fn_native_int_int_mul(__attr __args[]);
   12.14 -__attr __fn_native_int_int_neg(__attr __args[]);
   12.15 -__attr __fn_native_int_int_pow(__attr __args[]);
   12.16 -__attr __fn_native_int_int_sub(__attr __args[]);
   12.17 +__attr __fn_native_int_int_add(__attr __self, __attr _data, __attr other);
   12.18 +__attr __fn_native_int_int_sub(__attr __self, __attr _data, __attr other);
   12.19 +__attr __fn_native_int_int_mul(__attr __self, __attr _data, __attr other);
   12.20 +__attr __fn_native_int_int_div(__attr __self, __attr _data, __attr other);
   12.21 +__attr __fn_native_int_int_mod(__attr __self, __attr _data, __attr other);
   12.22 +__attr __fn_native_int_int_neg(__attr __self, __attr _data);
   12.23 +__attr __fn_native_int_int_pow(__attr __self, __attr _data, __attr other);
   12.24  
   12.25 -__attr __fn_native_int_int_and(__attr __args[]);
   12.26 -__attr __fn_native_int_int_not(__attr __args[]);
   12.27 -__attr __fn_native_int_int_or(__attr __args[]);
   12.28 -__attr __fn_native_int_int_xor(__attr __args[]);
   12.29 +__attr __fn_native_int_int_and(__attr __self, __attr _data, __attr other);
   12.30 +__attr __fn_native_int_int_not(__attr __self, __attr _data);
   12.31 +__attr __fn_native_int_int_or(__attr __self, __attr _data, __attr other);
   12.32 +__attr __fn_native_int_int_xor(__attr __self, __attr _data, __attr other);
   12.33  
   12.34 -__attr __fn_native_int_int_rdiv(__attr __args[]);
   12.35 -__attr __fn_native_int_int_rmod(__attr __args[]);
   12.36 -__attr __fn_native_int_int_rpow(__attr __args[]);
   12.37 -__attr __fn_native_int_int_rsub(__attr __args[]);
   12.38 +__attr __fn_native_int_int_lt(__attr __self, __attr _data, __attr other);
   12.39 +__attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other);
   12.40 +__attr __fn_native_int_int_eq(__attr __self, __attr _data, __attr other);
   12.41 +__attr __fn_native_int_int_ne(__attr __self, __attr _data, __attr other);
   12.42  
   12.43 -__attr __fn_native_int_int_lt(__attr __args[]);
   12.44 -__attr __fn_native_int_int_gt(__attr __args[]);
   12.45 -__attr __fn_native_int_int_eq(__attr __args[]);
   12.46 -__attr __fn_native_int_int_ne(__attr __args[]);
   12.47 -
   12.48 -__attr __fn_native_int_int_str(__attr __args[]);
   12.49 +__attr __fn_native_int_int_str(__attr __self, __attr _data);
   12.50  
   12.51  /* Module initialisation. */
   12.52  
    13.1 --- a/templates/native/introspection.c	Mon Mar 06 22:29:36 2017 +0100
    13.2 +++ b/templates/native/introspection.c	Tue Mar 07 00:28:18 2017 +0100
    13.3 @@ -26,56 +26,47 @@
    13.4  
    13.5  /* Introspection. */
    13.6  
    13.7 -__attr __fn_native_introspection_object_getattr(__attr __args[])
    13.8 +__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default)
    13.9  {
   13.10 -    __attr * const obj = &__args[1];
   13.11 -    __attr * const name = &__args[2];
   13.12 -    __attr * const _default = &__args[3];
   13.13 -    /* name.__data__ interpreted as string */
   13.14 -    __attr key = __load_via_object(name->value, __key__);
   13.15 +    /* name interpreted as string */
   13.16 +    __attr key = __load_via_object(name.value, __key__);
   13.17      __attr out;
   13.18  
   13.19      if ((key.code == 0) && (key.pos == 0))
   13.20 -        return *_default;
   13.21 +        return _default;
   13.22  
   13.23      /* Attempt to get the attribute from the object. */
   13.24  
   13.25 -    out = __check_and_load_via_object_null(obj->value, key.pos, key.code);
   13.26 +    out = __check_and_load_via_object_null(obj.value, key.pos, key.code);
   13.27      if (out.value == 0)
   13.28      {
   13.29          /* Inspect the object's class if this failed. */
   13.30  
   13.31 -        out = __check_and_load_via_class__(obj->value, key.pos, key.code);
   13.32 +        out = __check_and_load_via_class__(obj.value, key.pos, key.code);
   13.33          if (out.value == 0)
   13.34 -            return *_default;
   13.35 +            return _default;
   13.36  
   13.37          /* Update the context to the object if it is a method. */
   13.38  
   13.39 -        return __update_context(obj->value, out);
   13.40 +        return __update_context(obj.value, out);
   13.41      }
   13.42  
   13.43      return out;
   13.44  }
   13.45  
   13.46 -__attr __fn_native_introspection_isinstance(__attr __args[])
   13.47 +__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls)
   13.48  {
   13.49 -    __attr * const obj = &__args[1];
   13.50 -    __attr * const cls = &__args[2];
   13.51 -
   13.52      /* cls must be a class. */
   13.53 -    if (__is_instance_subclass(obj->value, *cls))
   13.54 +    if (__is_instance_subclass(obj.value, cls))
   13.55          return __builtins___boolean_True;
   13.56      else
   13.57          return __builtins___boolean_False;
   13.58  }
   13.59  
   13.60 -__attr __fn_native_introspection_issubclass(__attr __args[])
   13.61 +__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls)
   13.62  {
   13.63 -    __attr * const obj = &__args[1];
   13.64 -    __attr * const cls = &__args[2];
   13.65 -
   13.66      /* obj and cls must be classes. */
   13.67 -    if (__is_subclass(obj->value, *cls))
   13.68 +    if (__is_subclass(obj.value, cls))
   13.69          return __builtins___boolean_True;
   13.70      else
   13.71          return __builtins___boolean_False;
    14.1 --- a/templates/native/introspection.h	Mon Mar 06 22:29:36 2017 +0100
    14.2 +++ b/templates/native/introspection.h	Tue Mar 07 00:28:18 2017 +0100
    14.3 @@ -1,6 +1,6 @@
    14.4  /* Native functions for introspection.
    14.5  
    14.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    14.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    14.8  
    14.9  This program is free software; you can redistribute it and/or modify it under
   14.10  the terms of the GNU General Public License as published by the Free Software
   14.11 @@ -23,9 +23,9 @@
   14.12  
   14.13  /* Introspection. */
   14.14  
   14.15 -__attr __fn_native_introspection_object_getattr(__attr __args[]);
   14.16 -__attr __fn_native_introspection_isinstance(__attr __args[]);
   14.17 -__attr __fn_native_introspection_issubclass(__attr __args[]);
   14.18 +__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default);
   14.19 +__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls);
   14.20 +__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls);
   14.21  
   14.22  /* Module initialisation. */
   14.23  
    15.1 --- a/templates/native/io.c	Mon Mar 06 22:29:36 2017 +0100
    15.2 +++ b/templates/native/io.c	Tue Mar 07 00:28:18 2017 +0100
    15.3 @@ -31,11 +31,10 @@
    15.4  
    15.5  /* Input/output. */
    15.6  
    15.7 -__attr __fn_native_io_fclose(__attr __args[])
    15.8 +__attr __fn_native_io_fclose(__attr __self, __attr fp)
    15.9  {
   15.10 -    __attr * const fp = &__args[1];
   15.11      /* fp interpreted as FILE reference */
   15.12 -    FILE *f = (FILE *) fp->datavalue;
   15.13 +    FILE *f = (FILE *) fp.datavalue;
   15.14  
   15.15      errno = 0;
   15.16      if (fclose(f))
   15.17 @@ -44,11 +43,10 @@
   15.18      return __builtins___none_None;
   15.19  }
   15.20  
   15.21 -__attr __fn_native_io_fflush(__attr __args[])
   15.22 +__attr __fn_native_io_fflush(__attr __self, __attr fp)
   15.23  {
   15.24 -    __attr * const fp = &__args[1];
   15.25      /* fp interpreted as FILE reference */
   15.26 -    FILE *f = (FILE *) fp->datavalue;
   15.27 +    FILE *f = (FILE *) fp.datavalue;
   15.28  
   15.29      errno = 0;
   15.30      if (fflush(f))
   15.31 @@ -57,14 +55,12 @@
   15.32      return __builtins___none_None;
   15.33  }
   15.34  
   15.35 -__attr __fn_native_io_fopen(__attr __args[])
   15.36 +__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode)
   15.37  {
   15.38 -    __attr * const filename = &__args[1];
   15.39 -    __attr * const mode = &__args[2];
   15.40 -    /* filename.__data__ interpreted as string */
   15.41 -    char *fn = __load_via_object(filename->value, __data__).strvalue;
   15.42 -    /* mode.__data__ interpreted as string */
   15.43 -    char *s = __load_via_object(mode->value, __data__).strvalue;
   15.44 +    /* filename interpreted as string */
   15.45 +    char *fn = __load_via_object(filename.value, __data__).strvalue;
   15.46 +    /* mode interpreted as string */
   15.47 +    char *s = __load_via_object(mode.value, __data__).strvalue;
   15.48      FILE *f;
   15.49      __attr attr;
   15.50  
   15.51 @@ -89,14 +85,12 @@
   15.52      return __builtins___none_None;
   15.53  }
   15.54  
   15.55 -__attr __fn_native_io_fdopen(__attr __args[])
   15.56 +__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode)
   15.57  {
   15.58 -    __attr * const fd = &__args[1];
   15.59 -    __attr * const mode = &__args[2];
   15.60 -    /* fd.__data__ interpreted as int */
   15.61 -    int i = __load_via_object(fd->value, __data__).intvalue;
   15.62 -    /* mode.__data__ interpreted as string */
   15.63 -    char *s = __load_via_object(mode->value, __data__).strvalue;
   15.64 +    /* fd interpreted as int */
   15.65 +    int i = __load_via_object(fd.value, __data__).intvalue;
   15.66 +    /* mode interpreted as string */
   15.67 +    char *s = __load_via_object(mode.value, __data__).strvalue;
   15.68      FILE *f;
   15.69      __attr attr;
   15.70  
   15.71 @@ -121,14 +115,12 @@
   15.72      return __builtins___none_None;
   15.73  }
   15.74  
   15.75 -__attr __fn_native_io_fread(__attr __args[])
   15.76 +__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size)
   15.77  {
   15.78 -    __attr * const fp = &__args[1];
   15.79 -    __attr * const size = &__args[2];
   15.80      /* fp interpreted as FILE reference */
   15.81 -    FILE *f = (FILE *) fp->datavalue;
   15.82 -    /* size.__data__ interpreted as int */
   15.83 -    int to_read = __load_via_object(size->value, __data__).intvalue;
   15.84 +    FILE *f = (FILE *) fp.datavalue;
   15.85 +    /* size interpreted as int */
   15.86 +    int to_read = __load_via_object(size.value, __data__).intvalue;
   15.87      char buf[to_read];
   15.88      size_t have_read;
   15.89      int error;
   15.90 @@ -151,15 +143,12 @@
   15.91      return __new_str(s, have_read);
   15.92  }
   15.93  
   15.94 -__attr __fn_native_io_fwrite(__attr __args[])
   15.95 +__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str)
   15.96  {
   15.97 -    __attr * const fp = &__args[1];
   15.98 -    __attr * const str = &__args[2];
   15.99      /* fp interpreted as FILE reference */
  15.100 -    FILE *f = (FILE *) fp->datavalue;
  15.101 -    /* str.__data__ interpreted as string */
  15.102 -    char *s = __load_via_object(str->value, __data__).strvalue;
  15.103 -    /* str.__size__ interpreted as int */
  15.104 +    FILE *f = (FILE *) fp.datavalue;
  15.105 +    /* str interpreted as string */
  15.106 +    char *s = __load_via_object(str.value, __data__).strvalue;
  15.107      int to_write = __load_via_object(str->value, __size__).intvalue;
  15.108      size_t have_written = fwrite(s, sizeof(char), to_write, f);
  15.109      int error;
  15.110 @@ -175,11 +164,10 @@
  15.111      return __builtins___none_None;
  15.112  }
  15.113  
  15.114 -__attr __fn_native_io_close(__attr __args[])
  15.115 +__attr __fn_native_io_close(__attr __self, __attr fd)
  15.116  {
  15.117 -    __attr * const fd = &__args[1];
  15.118 -    /* fd.__data__ interpreted as int */
  15.119 -    int i = __load_via_object(fd->value, __data__).intvalue;
  15.120 +    /* fd interpreted as int */
  15.121 +    int i = __load_via_object(fd.value, __data__).intvalue;
  15.122  
  15.123      errno = 0;
  15.124      if (close(i) == -1)
  15.125 @@ -188,14 +176,12 @@
  15.126      return __builtins___none_None;
  15.127  }
  15.128  
  15.129 -__attr __fn_native_io_read(__attr __args[])
  15.130 +__attr __fn_native_io_read(__attr __self, __attr fd, __attr n)
  15.131  {
  15.132 -    __attr * const fd = &__args[1];
  15.133 -    __attr * const n = &__args[2];
  15.134 -    /* fd.__data__ interpreted as int */
  15.135 -    int i = __load_via_object(fd->value, __data__).intvalue;
  15.136 -    /* n.__data__ interpreted as int */
  15.137 -    int to_read = __load_via_object(n->value, __data__).intvalue;
  15.138 +    /* fd interpreted as int */
  15.139 +    int i = __load_via_object(fd.value, __data__).intvalue;
  15.140 +    /* n interpreted as int */
  15.141 +    int to_read = __load_via_object(n.value, __data__).intvalue;
  15.142      char buf[to_read];
  15.143      ssize_t have_read;
  15.144      char *s;
  15.145 @@ -213,16 +199,13 @@
  15.146      return __new_str(s, have_read);
  15.147  }
  15.148  
  15.149 -__attr __fn_native_io_write(__attr __args[])
  15.150 +__attr __fn_native_io_write(__attr __self, __attr fd, __attr str)
  15.151  {
  15.152 -    __attr * const fd = &__args[1];
  15.153 -    __attr * const str = &__args[2];
  15.154 -    /* fd.__data__ interpreted as int */
  15.155 -    int i = __load_via_object(fd->value, __data__).intvalue;
  15.156 -    /* str.__data__ interpreted as string */
  15.157 -    char *s = __load_via_object(str->value, __data__).strvalue;
  15.158 -    /* str.__size__ interpreted as int */
  15.159 -    int size = __load_via_object(str->value, __size__).intvalue;
  15.160 +    /* fd interpreted as int */
  15.161 +    int i = __load_via_object(fd.value, __data__).intvalue;
  15.162 +    /* str interpreted as string */
  15.163 +    char *s = __load_via_object(str.value, __data__).strvalue;
  15.164 +    int size = __load_via_object(str.value, __size__).intvalue;
  15.165      ssize_t have_written;
  15.166  
  15.167      errno = 0;
    16.1 --- a/templates/native/io.h	Mon Mar 06 22:29:36 2017 +0100
    16.2 +++ b/templates/native/io.h	Tue Mar 07 00:28:18 2017 +0100
    16.3 @@ -1,6 +1,6 @@
    16.4  /* Native functions for input/output.
    16.5  
    16.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    16.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    16.8  
    16.9  This program is free software; you can redistribute it and/or modify it under
   16.10  the terms of the GNU General Public License as published by the Free Software
   16.11 @@ -23,15 +23,15 @@
   16.12  
   16.13  /* Input/output. */
   16.14  
   16.15 -__attr __fn_native_io_fclose(__attr __args[]);
   16.16 -__attr __fn_native_io_fflush(__attr __args[]);
   16.17 -__attr __fn_native_io_fopen(__attr __args[]);
   16.18 -__attr __fn_native_io_fdopen(__attr __args[]);
   16.19 -__attr __fn_native_io_fread(__attr __args[]);
   16.20 -__attr __fn_native_io_fwrite(__attr __args[]);
   16.21 -__attr __fn_native_io_close(__attr __args[]);
   16.22 -__attr __fn_native_io_read(__attr __args[]);
   16.23 -__attr __fn_native_io_write(__attr __args[]);
   16.24 +__attr __fn_native_io_fclose(__attr __self, __attr fp);
   16.25 +__attr __fn_native_io_fflush(__attr __self, __attr fp);
   16.26 +__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode);
   16.27 +__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode);
   16.28 +__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size);
   16.29 +__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str);
   16.30 +__attr __fn_native_io_close(__attr __self, __attr fd);
   16.31 +__attr __fn_native_io_read(__attr __self, __attr fd, __attr n);
   16.32 +__attr __fn_native_io_write(__attr __self, __attr fd, __attr str);
   16.33  
   16.34  /* Module initialisation. */
   16.35  
    17.1 --- a/templates/native/limits.c	Mon Mar 06 22:29:36 2017 +0100
    17.2 +++ b/templates/native/limits.c	Tue Mar 07 00:28:18 2017 +0100
    17.3 @@ -1,6 +1,6 @@
    17.4  /* Native functions for limit definition.
    17.5  
    17.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    17.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    17.8  
    17.9  This program is free software; you can redistribute it and/or modify it under
   17.10  the terms of the GNU General Public License as published by the Free Software
   17.11 @@ -28,12 +28,12 @@
   17.12  
   17.13  /* Limit definition. */
   17.14  
   17.15 -__attr __fn_native_limits_get_maxint(__attr __args[])
   17.16 +__attr __fn_native_limits_get_maxint(__attr __self)
   17.17  {
   17.18      return __new_int(INT_MAX);
   17.19  }
   17.20  
   17.21 -__attr __fn_native_limits_get_minint(__attr __args[])
   17.22 +__attr __fn_native_limits_get_minint(__attr __self)
   17.23  {
   17.24      return __new_int(INT_MIN);
   17.25  }
    18.1 --- a/templates/native/limits.h	Mon Mar 06 22:29:36 2017 +0100
    18.2 +++ b/templates/native/limits.h	Tue Mar 07 00:28:18 2017 +0100
    18.3 @@ -1,6 +1,6 @@
    18.4  /* Native functions for limit definition.
    18.5  
    18.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    18.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    18.8  
    18.9  This program is free software; you can redistribute it and/or modify it under
   18.10  the terms of the GNU General Public License as published by the Free Software
   18.11 @@ -23,8 +23,8 @@
   18.12  
   18.13  /* Limit definition. */
   18.14  
   18.15 -__attr __fn_native_limits_get_maxint(__attr __args[]);
   18.16 -__attr __fn_native_limits_get_minint(__attr __args[]);
   18.17 +__attr __fn_native_limits_get_maxint(__attr __self);
   18.18 +__attr __fn_native_limits_get_minint(__attr __self);
   18.19  
   18.20  /* Module initialisation. */
   18.21  
    19.1 --- a/templates/native/list.c	Mon Mar 06 22:29:36 2017 +0100
    19.2 +++ b/templates/native/list.c	Tue Mar 07 00:28:18 2017 +0100
    19.3 @@ -27,51 +27,44 @@
    19.4  
    19.5  /* List operations. */
    19.6  
    19.7 -__attr __fn_native_list_list_init(__attr __args[])
    19.8 +__attr __fn_native_list_list_init(__attr __self, __attr size)
    19.9  {
   19.10 -    __attr * const size = &__args[1];
   19.11 -    /* size.__data__ interpreted as int */
   19.12 -    unsigned int n = __load_via_object(size->value, __data__).intvalue;
   19.13 +    /* size interpreted as int */
   19.14 +    unsigned int n = __load_via_object(size.value, __data__).intvalue;
   19.15      __attr attr = {.seqvalue=__new_fragment(n)};
   19.16  
   19.17      /* Return the __data__ attribute. */
   19.18      return attr;
   19.19  }
   19.20  
   19.21 -__attr __fn_native_list_list_setsize(__attr __args[])
   19.22 +__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size)
   19.23  {
   19.24 -    __attr * const _data = &__args[1];
   19.25 -    __attr * const size = &__args[2];
   19.26 -    /* _data interpreted as list */
   19.27 -    __fragment *data = _data->seqvalue;
   19.28 -    /* size.__data__ interpreted as int */
   19.29 -    unsigned int n = __load_via_object(size->value, __data__).intvalue;
   19.30 +    /* _data interpreted as list.__data__ */
   19.31 +    __fragment *data = _data.seqvalue;
   19.32 +    /* size interpreted as int */
   19.33 +    unsigned int n = __load_via_object(size.value, __data__).intvalue;
   19.34  
   19.35      data->size = n;
   19.36      return __builtins___none_None;
   19.37  }
   19.38  
   19.39 -__attr __fn_native_list_list_append(__attr __args[])
   19.40 +__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value)
   19.41  {
   19.42 -    __attr * const self = &__args[1];
   19.43 -    __attr * const value = &__args[2];
   19.44 -    /* self.__data__ interpreted as list */
   19.45 -    __fragment *data = __load_via_object(self->value, __data__).seqvalue;
   19.46 +    /* self interpreted as list */
   19.47 +    __fragment *data = __load_via_object(self.value, __data__).seqvalue;
   19.48      __fragment *newdata = __fragment_append(data, value);
   19.49  
   19.50      /* Replace the __data__ attribute if appropriate. */
   19.51      if (newdata != data)
   19.52 -        __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata}));
   19.53 +        __store_via_object(self.value, __data__, ((__attr) {.seqvalue=newdata}));
   19.54      return __builtins___none_None;
   19.55  }
   19.56  
   19.57 -__attr __fn_native_list_list_concat(__attr __args[])
   19.58 +__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other)
   19.59  {
   19.60 -    __attr * const self = &__args[1];
   19.61 -    __attr * const other = &__args[2];
   19.62 -    /* self.__data__, other interpreted as list */
   19.63 -    __fragment *data = __load_via_object(self->value, __data__).seqvalue;
   19.64 -    __fragment *other_data = other->seqvalue;
   19.65 +    /* self, interpreted as list, other interpreted as list.__data__ */
   19.66 +    __fragment *data = __load_via_object(self.value, __data__).seqvalue;
   19.67 +    __fragment *other_data = other.seqvalue;
   19.68      __fragment *newdata = data;
   19.69      unsigned int size = data->size, capacity = data->capacity;
   19.70      unsigned int other_size = other_data->size;
   19.71 @@ -91,51 +84,43 @@
   19.72  
   19.73      /* Replace the __data__ attribute if appropriate. */
   19.74      if (newdata != data)
   19.75 -        __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata}));
   19.76 +        __store_via_object(self.value, __data__, ((__attr) {.seqvalue=newdata}));
   19.77      return __builtins___none_None;
   19.78  }
   19.79  
   19.80 -__attr __fn_native_list_list_len(__attr __args[])
   19.81 +__attr __fn_native_list_list_len(__attr self, __attr _data)
   19.82  {
   19.83 -    __attr * const _data = &__args[1];
   19.84 -    /* _data interpreted as fragment */
   19.85 -    unsigned int size = _data->seqvalue->size;
   19.86 +    /* _data interpreted as list.__data__ */
   19.87 +    unsigned int size = _data.seqvalue->size;
   19.88  
   19.89      /* Return the new integer. */
   19.90      return __new_int(size);
   19.91  }
   19.92  
   19.93 -__attr __fn_native_list_list_nonempty(__attr __args[])
   19.94 +__attr __fn_native_list_list_nonempty(__attr __self, __attr _data)
   19.95  {
   19.96 -    __attr * const _data = &__args[1];
   19.97 -
   19.98 -    return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False;
   19.99 +    return _data.seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False;
  19.100  }
  19.101  
  19.102 -__attr __fn_native_list_list_element(__attr __args[])
  19.103 +__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index)
  19.104  {
  19.105 -    __attr * const _data = &__args[1];
  19.106 -    __attr * const index = &__args[2];
  19.107 -    /* _data interpreted as fragment */
  19.108 -    __attr *elements = _data->seqvalue->attrs;
  19.109 -    /* index.__data__ interpreted as int */
  19.110 -    int i = __load_via_object(index->value, __data__).intvalue;
  19.111 +    /* _data interpreted as list.__data__ */
  19.112 +    __attr *elements = _data.seqvalue->attrs;
  19.113 +    /* index interpreted as int */
  19.114 +    int i = __load_via_object(index.value, __data__).intvalue;
  19.115  
  19.116      return elements[i];
  19.117  }
  19.118  
  19.119 -__attr __fn_native_list_list_setelement(__attr __args[])
  19.120 +__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value)
  19.121  {
  19.122 -    __attr * const _data = &__args[1];
  19.123 -    __attr * const index = &__args[2];
  19.124 -    __attr * const value = &__args[3];
  19.125 -    /* _data interpreted as fragment */
  19.126 -    __attr *elements = _data->seqvalue->attrs;
  19.127 -    /* index.__data__ interpreted as int */
  19.128 -    int i = __load_via_object(index->value, __data__).intvalue;
  19.129 +    /* _data interpreted as list.__data__ */
  19.130 +    __attr *elements = _data.seqvalue->attrs;
  19.131 +    /* index interpreted as int */
  19.132 +    int i = __load_via_object(index.value, __data__).intvalue;
  19.133  
  19.134      /* Set the element. */
  19.135 -    elements[i] = *value;
  19.136 +    elements[i] = value;
  19.137      return __builtins___none_None;
  19.138  }
  19.139  
    20.1 --- a/templates/native/list.h	Mon Mar 06 22:29:36 2017 +0100
    20.2 +++ b/templates/native/list.h	Tue Mar 07 00:28:18 2017 +0100
    20.3 @@ -1,6 +1,6 @@
    20.4  /* Native functions for list operations.
    20.5  
    20.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    20.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    20.8  
    20.9  This program is free software; you can redistribute it and/or modify it under
   20.10  the terms of the GNU General Public License as published by the Free Software
   20.11 @@ -23,14 +23,14 @@
   20.12  
   20.13  /* List operations. */
   20.14  
   20.15 -__attr __fn_native_list_list_init(__attr __args[]);
   20.16 -__attr __fn_native_list_list_setsize(__attr __args[]);
   20.17 -__attr __fn_native_list_list_append(__attr __args[]);
   20.18 -__attr __fn_native_list_list_concat(__attr __args[]);
   20.19 -__attr __fn_native_list_list_len(__attr __args[]);
   20.20 -__attr __fn_native_list_list_nonempty(__attr __args[]);
   20.21 -__attr __fn_native_list_list_element(__attr __args[]);
   20.22 -__attr __fn_native_list_list_setelement(__attr __args[]);
   20.23 +__attr __fn_native_list_list_init(__attr __self, __attr size);
   20.24 +__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size);
   20.25 +__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value);
   20.26 +__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other);
   20.27 +__attr __fn_native_list_list_len(__attr self, __attr _data);
   20.28 +__attr __fn_native_list_list_nonempty(__attr __self, __attr _data);
   20.29 +__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index);
   20.30 +__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value);
   20.31  
   20.32  /* Module initialisation. */
   20.33  
    21.1 --- a/templates/native/locale.c	Mon Mar 06 22:29:36 2017 +0100
    21.2 +++ b/templates/native/locale.c	Tue Mar 07 00:28:18 2017 +0100
    21.3 @@ -29,11 +29,10 @@
    21.4  
    21.5  /* Locales. */
    21.6  
    21.7 -__attr __fn_native_locale_getlocale(__attr __args[])
    21.8 +__attr __fn_native_locale_getlocale(__attr __self, __attr category)
    21.9  {
   21.10 -    __attr * const category = &__args[1];
   21.11 -    /* category.__data__ interpreted as int */
   21.12 -    int cat = __load_via_object(category->value, __data__).intvalue;
   21.13 +    /* category interpreted as int */
   21.14 +    int cat = __load_via_object(category.value, __data__).intvalue;
   21.15      char *result, *out;
   21.16      size_t length;
   21.17  
   21.18 @@ -49,14 +48,12 @@
   21.19      return __new_str(result, length);
   21.20  }
   21.21  
   21.22 -__attr __fn_native_locale_setlocale(__attr __args[])
   21.23 +__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value)
   21.24  {
   21.25 -    __attr * const category = &__args[1];
   21.26 -    __attr * const value = &__args[2];
   21.27 -    /* category.__data__ interpreted as int */
   21.28 -    int cat = __load_via_object(category->value, __data__).intvalue;
   21.29 -    /* value.__data__ interpreted as string */
   21.30 -    char *s = __load_via_object(value->value, __data__).strvalue;
   21.31 +    /* category interpreted as int */
   21.32 +    int cat = __load_via_object(category.value, __data__).intvalue;
   21.33 +    /* value interpreted as string */
   21.34 +    char *s = __load_via_object(value.value, __data__).strvalue;
   21.35      char *result, *out;
   21.36      size_t length;
   21.37  
    22.1 --- a/templates/native/locale.h	Mon Mar 06 22:29:36 2017 +0100
    22.2 +++ b/templates/native/locale.h	Tue Mar 07 00:28:18 2017 +0100
    22.3 @@ -1,6 +1,6 @@
    22.4  /* Native functions for locale handling.
    22.5  
    22.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    22.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    22.8  
    22.9  This program is free software; you can redistribute it and/or modify it under
   22.10  the terms of the GNU General Public License as published by the Free Software
   22.11 @@ -23,8 +23,8 @@
   22.12  
   22.13  /* Input/output. */
   22.14  
   22.15 -__attr __fn_native_locale_getlocale(__attr __args[]);
   22.16 -__attr __fn_native_locale_setlocale(__attr __args[]);
   22.17 +__attr __fn_native_locale_getlocale(__attr __self, __attr category);
   22.18 +__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value);
   22.19  
   22.20  /* Module initialisation. */
   22.21  
    23.1 --- a/templates/native/program.c	Mon Mar 06 22:29:36 2017 +0100
    23.2 +++ b/templates/native/program.c	Tue Mar 07 00:28:18 2017 +0100
    23.3 @@ -26,12 +26,9 @@
    23.4  
    23.5  /* Method binding. */
    23.6  
    23.7 -__attr __fn_native_program_get_using(__attr __args[])
    23.8 +__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance)
    23.9  {
   23.10 -    __attr * const callable = &__args[1];
   23.11 -    __attr * const instance = &__args[2];
   23.12 -
   23.13 -    return __test_context(instance->value, *callable);
   23.14 +    return __test_context(instance.value, callable);
   23.15  }
   23.16  
   23.17  /* Module initialisation. */
    24.1 --- a/templates/native/program.h	Mon Mar 06 22:29:36 2017 +0100
    24.2 +++ b/templates/native/program.h	Tue Mar 07 00:28:18 2017 +0100
    24.3 @@ -1,6 +1,6 @@
    24.4  /* Native functions for program operations.
    24.5  
    24.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    24.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    24.8  
    24.9  This program is free software; you can redistribute it and/or modify it under
   24.10  the terms of the GNU General Public License as published by the Free Software
   24.11 @@ -21,7 +21,7 @@
   24.12  
   24.13  /* Method binding. */
   24.14  
   24.15 -__attr __fn_native_program_get_using(__attr __args[]);
   24.16 +__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance);
   24.17  
   24.18  /* Module initialisation. */
   24.19  
    25.1 --- a/templates/native/str.c	Mon Mar 06 22:29:36 2017 +0100
    25.2 +++ b/templates/native/str.c	Tue Mar 07 00:28:18 2017 +0100
    25.3 @@ -28,16 +28,13 @@
    25.4  
    25.5  /* String operations. */
    25.6  
    25.7 -__attr __fn_native_str_str_add(__attr __args[])
    25.8 +__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize)
    25.9  {
   25.10 -    __attr * const _data = &__args[1];
   25.11 -    __attr * const other = &__args[2];
   25.12 -    __attr * const _size = &__args[3];
   25.13 -    __attr * const othersize = &__args[4];
   25.14 -    /* _data, other interpreted as string */
   25.15 -    char *s = _data->strvalue;
   25.16 -    char *o = other->strvalue;
   25.17 -    int ss = _size->intvalue, os = othersize->intvalue;
   25.18 +    /* _data, other interpreted as string.__data__ */
   25.19 +    char *s = _data.strvalue;
   25.20 +    char *o = other.strvalue;
   25.21 +    /* _size, othersize interpreted as int.__data__ */
   25.22 +    int ss = _size.intvalue, os = othersize.intvalue;
   25.23      int n = ss + os;
   25.24      char *r = (char *) __ALLOCATE(n + 1, sizeof(char));
   25.25  
   25.26 @@ -48,76 +45,64 @@
   25.27      return __new_str(r, n);
   25.28  }
   25.29  
   25.30 -__attr __fn_native_str_str_chr(__attr __args[])
   25.31 +__attr __fn_native_str_str_chr(__attr __self, __attr _data)
   25.32  {
   25.33 -    __attr * const _data = &__args[1];
   25.34 -    /* _data interpreted as int */
   25.35 -    int n = _data->intvalue;
   25.36 +    /* _data interpreted as int.__data__ */
   25.37 +    int n = _data.intvalue;
   25.38      char *s = (char *) __ALLOCATE(2, sizeof(char));
   25.39  
   25.40      s[0] = (char) n;
   25.41      return __new_str(s, 1);
   25.42  }
   25.43  
   25.44 -__attr __fn_native_str_str_lt(__attr __args[])
   25.45 +__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other)
   25.46  {
   25.47 -    __attr * const _data = &__args[1];
   25.48 -    __attr * const other = &__args[2];
   25.49 -    /* _data, other interpreted as string */
   25.50 -    char *s = _data->strvalue;
   25.51 -    char *o = other->strvalue;
   25.52 +    /* _data, other interpreted as string.__data__ */
   25.53 +    char *s = _data.strvalue;
   25.54 +    char *o = other.strvalue;
   25.55  
   25.56      /* NOTE: Using simple byte-level string operations. */
   25.57      return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False;
   25.58  }
   25.59  
   25.60 -__attr __fn_native_str_str_gt(__attr __args[])
   25.61 +__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other)
   25.62  {
   25.63 -    __attr * const _data = &__args[1];
   25.64 -    __attr * const other = &__args[2];
   25.65 -    /* _data, other interpreted as string */
   25.66 -    char *s = _data->strvalue;
   25.67 -    char *o = other->strvalue;
   25.68 +    /* _data, other interpreted as string.__data__ */
   25.69 +    char *s = _data.strvalue;
   25.70 +    char *o = other.strvalue;
   25.71  
   25.72      /* NOTE: Using simple byte-level string operations. */
   25.73      return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False;
   25.74  }
   25.75  
   25.76 -__attr __fn_native_str_str_eq(__attr __args[])
   25.77 +__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other)
   25.78  {
   25.79 -    __attr * const _data = &__args[1];
   25.80 -    __attr * const other = &__args[2];
   25.81 -    /* _data, other interpreted as string */
   25.82 -    char *s = _data->strvalue;
   25.83 -    char *o = other->strvalue;
   25.84 +    /* _data, other interpreted as string.__data__ */
   25.85 +    char *s = _data.strvalue;
   25.86 +    char *o = other.strvalue;
   25.87  
   25.88      /* NOTE: Using simple byte-level string operations. */
   25.89      return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False;
   25.90  }
   25.91  
   25.92 -__attr __fn_native_str_str_ord(__attr __args[])
   25.93 +__attr __fn_native_str_str_ord(__attr __self, __attr _data)
   25.94  {
   25.95 -    __attr * const _data = &__args[1];
   25.96 -    /* _data interpreted as string */
   25.97 -    char *s = _data->strvalue;
   25.98 +    /* _data interpreted as string.__data__ */
   25.99 +    char *s = _data.strvalue;
  25.100  
  25.101      return __new_int((unsigned int) s[0]);
  25.102  }
  25.103  
  25.104 -__attr __fn_native_str_str_substr(__attr __args[])
  25.105 +__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step)
  25.106  {
  25.107 -    __attr * const _data = &__args[1];
  25.108 -    __attr * const start = &__args[2];
  25.109 -    __attr * const end = &__args[3];
  25.110 -    __attr * const step = &__args[4];
  25.111 -    /* _data interpreted as string */
  25.112 -    char *s = _data->strvalue, *sub;
  25.113 -    /* start.__data__ interpreted as int */
  25.114 -    int istart = __load_via_object(start->value, __data__).intvalue;
  25.115 -    /* end.__data__ interpreted as int */
  25.116 -    int iend = __load_via_object(end->value, __data__).intvalue;
  25.117 -    /* step.__data__ interpreted as int */
  25.118 -    int istep = __load_via_object(step->value, __data__).intvalue;
  25.119 +    /* _data interpreted as string.__data__ */
  25.120 +    char *s = _data.strvalue, *sub;
  25.121 +    /* start interpreted as int */
  25.122 +    int istart = __load_via_object(start.value, __data__).intvalue;
  25.123 +    /* end interpreted as int */
  25.124 +    int iend = __load_via_object(end.value, __data__).intvalue;
  25.125 +    /* step interpreted as int */
  25.126 +    int istep = __load_via_object(step.value, __data__).intvalue;
  25.127  
  25.128      /* Calculate the size of the substring. */
  25.129      size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1;
    26.1 --- a/templates/native/str.h	Mon Mar 06 22:29:36 2017 +0100
    26.2 +++ b/templates/native/str.h	Tue Mar 07 00:28:18 2017 +0100
    26.3 @@ -21,13 +21,13 @@
    26.4  
    26.5  /* String operations. */
    26.6  
    26.7 -__attr __fn_native_str_str_add(__attr __args[]);
    26.8 -__attr __fn_native_str_str_chr(__attr __args[]);
    26.9 -__attr __fn_native_str_str_lt(__attr __args[]);
   26.10 -__attr __fn_native_str_str_gt(__attr __args[]);
   26.11 -__attr __fn_native_str_str_eq(__attr __args[]);
   26.12 -__attr __fn_native_str_str_ord(__attr __args[]);
   26.13 -__attr __fn_native_str_str_substr(__attr __args[]);
   26.14 +__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize);
   26.15 +__attr __fn_native_str_str_chr(__attr __self, __attr _data);
   26.16 +__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other);
   26.17 +__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other);
   26.18 +__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other);
   26.19 +__attr __fn_native_str_str_ord(__attr __self, __attr _data);
   26.20 +__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step);
   26.21  
   26.22  /* Module initialisation. */
   26.23  
    27.1 --- a/templates/native/system.c	Mon Mar 06 22:29:36 2017 +0100
    27.2 +++ b/templates/native/system.c	Tue Mar 07 00:28:18 2017 +0100
    27.3 @@ -27,21 +27,19 @@
    27.4  
    27.5  /* Environment support. */
    27.6  
    27.7 -__attr __fn_native_system_exit(__attr __args[])
    27.8 +__attr __fn_native_system_exit(__attr __self, __attr status)
    27.9  {
   27.10 -    __attr * const status = &__args[1];
   27.11 -
   27.12 -    exit(__load_via_object(status->value, __data__).intvalue);
   27.13 +    exit(__load_via_object(status.value, __data__).intvalue);
   27.14      return __builtins___none_None;
   27.15  }
   27.16  
   27.17 -__attr __fn_native_system_get_argv(__attr __args[])
   27.18 +__attr __fn_native_system_get_argv(__attr __self)
   27.19  {
   27.20      /* NOTE: To be written. */
   27.21      return __builtins___none_None;
   27.22  }
   27.23  
   27.24 -__attr __fn_native_system_get_path(__attr __args[])
   27.25 +__attr __fn_native_system_get_path(__attr __self)
   27.26  {
   27.27      /* NOTE: To be written. */
   27.28      return __builtins___none_None;
    28.1 --- a/templates/native/system.h	Mon Mar 06 22:29:36 2017 +0100
    28.2 +++ b/templates/native/system.h	Tue Mar 07 00:28:18 2017 +0100
    28.3 @@ -1,6 +1,6 @@
    28.4  /* Native functions for system operations.
    28.5  
    28.6 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
    28.7 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    28.8  
    28.9  This program is free software; you can redistribute it and/or modify it under
   28.10  the terms of the GNU General Public License as published by the Free Software
   28.11 @@ -23,9 +23,9 @@
   28.12  
   28.13  /* Environment support. */
   28.14  
   28.15 -__attr __fn_native_system_exit(__attr __args[]);
   28.16 -__attr __fn_native_system_get_argv(__attr __args[]);
   28.17 -__attr __fn_native_system_get_path(__attr __args[]);
   28.18 +__attr __fn_native_system_exit(__attr __self, __attr status);
   28.19 +__attr __fn_native_system_get_argv(__attr __self);
   28.20 +__attr __fn_native_system_get_path(__attr __self);
   28.21  
   28.22  /* Module initialisation. */
   28.23  
    29.1 --- a/templates/native/unicode.c	Mon Mar 06 22:29:36 2017 +0100
    29.2 +++ b/templates/native/unicode.c	Tue Mar 07 00:28:18 2017 +0100
    29.3 @@ -69,14 +69,12 @@
    29.4  
    29.5  /* Unicode operations. */
    29.6  
    29.7 -__attr __fn_native_unicode_unicode_len(__attr __args[])
    29.8 +__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size)
    29.9  {
   29.10 -    __attr * const _data = &__args[1];
   29.11 -    __attr * const _size = &__args[2];
   29.12 -    /* _data interpreted as string */
   29.13 -    char *s = _data->strvalue;
   29.14 -    /* _size interpreted as int */
   29.15 -    int size = _size->intvalue;
   29.16 +    /* _data interpreted as string.__data__ */
   29.17 +    char *s = _data.strvalue;
   29.18 +    /* _size interpreted as int.__data__ */
   29.19 +    int size = _size.intvalue;
   29.20      unsigned int i, c = 0;
   29.21  
   29.22      for (i = 0; i < size; i++)
   29.23 @@ -87,14 +85,12 @@
   29.24      return __new_int(c);
   29.25  }
   29.26  
   29.27 -__attr __fn_native_unicode_unicode_ord(__attr __args[])
   29.28 +__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size)
   29.29  {
   29.30 -    __attr * const _data = &__args[1];
   29.31 -    __attr * const _size = &__args[2];
   29.32 -    /* _data interpreted as string */
   29.33 -    char *s = _data->strvalue;
   29.34 -    /* _size interpreted as int */
   29.35 -    int size = _size->intvalue;
   29.36 +    /* _data interpreted as string.__data__ */
   29.37 +    char *s = _data.strvalue;
   29.38 +    /* _size interpreted as int.__data__ */
   29.39 +    int size = _size.intvalue;
   29.40      unsigned int i, c = 0, v;
   29.41  
   29.42      for (i = 0; i < size; i++)
   29.43 @@ -123,23 +119,18 @@
   29.44      return __new_int(c);
   29.45  }
   29.46  
   29.47 -__attr __fn_native_unicode_unicode_substr(__attr __args[])
   29.48 +__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step)
   29.49  {
   29.50 -    __attr * const _data = &__args[1];
   29.51 -    __attr * const _size = &__args[2];
   29.52 -    __attr * const start = &__args[3];
   29.53 -    __attr * const end = &__args[4];
   29.54 -    __attr * const step = &__args[5];
   29.55 -    /* _data interpreted as string */
   29.56 -    char *s = _data->strvalue, *sub;
   29.57 -    /* _size interpreted as int */
   29.58 -    int ss = _size->intvalue;
   29.59 -    /* start.__data__ interpreted as int */
   29.60 -    int istart = __load_via_object(start->value, __data__).intvalue;
   29.61 -    /* end.__data__ interpreted as int */
   29.62 -    int iend = __load_via_object(end->value, __data__).intvalue;
   29.63 -    /* step.__data__ interpreted as int */
   29.64 -    int istep = __load_via_object(step->value, __data__).intvalue;
   29.65 +    /* _data interpreted as string.__data__ */
   29.66 +    char *s = _data.strvalue, *sub;
   29.67 +    /* _size interpreted as int.__data__ */
   29.68 +    int ss = _size.intvalue;
   29.69 +    /* start interpreted as int */
   29.70 +    int istart = __load_via_object(start.value, __data__).intvalue;
   29.71 +    /* end interpreted as int */
   29.72 +    int iend = __load_via_object(end.value, __data__).intvalue;
   29.73 +    /* step interpreted as int */
   29.74 +    int istep = __load_via_object(step.value, __data__).intvalue;
   29.75  
   29.76      /* Calculate the number of characters. */
   29.77      size_t nchar = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1;
   29.78 @@ -202,11 +193,10 @@
   29.79      return __new_str(sub, resultsize);
   29.80  }
   29.81  
   29.82 -__attr __fn_native_unicode_unicode_unichr(__attr __args[])
   29.83 +__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value)
   29.84  {
   29.85 -    __attr * const value = &__args[1];
   29.86 -    /* value interpreted as int */
   29.87 -    int i = value->intvalue;
   29.88 +    /* value interpreted as int.__data__ */
   29.89 +    int i = value.intvalue;
   29.90      unsigned int resultsize;
   29.91      char *s;
   29.92  
    30.1 --- a/templates/native/unicode.h	Mon Mar 06 22:29:36 2017 +0100
    30.2 +++ b/templates/native/unicode.h	Tue Mar 07 00:28:18 2017 +0100
    30.3 @@ -21,10 +21,10 @@
    30.4  
    30.5  /* Unicode operations. */
    30.6  
    30.7 -__attr __fn_native_unicode_unicode_len(__attr __args[]);
    30.8 -__attr __fn_native_unicode_unicode_ord(__attr __args[]);
    30.9 -__attr __fn_native_unicode_unicode_substr(__attr __args[]);
   30.10 -__attr __fn_native_unicode_unicode_unichr(__attr __args[]);
   30.11 +__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size);
   30.12 +__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size);
   30.13 +__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step);
   30.14 +__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value);
   30.15  
   30.16  /* Module initialisation. */
   30.17  
    31.1 --- a/templates/ops.c	Mon Mar 06 22:29:36 2017 +0100
    31.2 +++ b/templates/ops.c	Tue Mar 07 00:28:18 2017 +0100
    31.3 @@ -308,7 +308,7 @@
    31.4      return value.value ? value : callable;
    31.5  }
    31.6  
    31.7 -__attr (*__get_function(__ref context, __attr target))(__attr[])
    31.8 +__attr (*__get_function(__ref context, __attr target))()
    31.9  {
   31.10      target = __unwrap_callable(target);
   31.11  
   31.12 @@ -321,7 +321,7 @@
   31.13          return __unbound_method;
   31.14  }
   31.15  
   31.16 -__attr (*__check_and_get_function(__ref context, __attr target))(__attr[])
   31.17 +__attr (*__check_and_get_function(__ref context, __attr target))()
   31.18  {
   31.19      target = __unwrap_callable(target);
   31.20  
    32.1 --- a/templates/ops.h	Mon Mar 06 22:29:36 2017 +0100
    32.2 +++ b/templates/ops.h	Tue Mar 07 00:28:18 2017 +0100
    32.3 @@ -108,8 +108,8 @@
    32.4  /* Context testing for invocations. */
    32.5  
    32.6  __attr __unwrap_callable(__attr callable);
    32.7 -__attr (*__get_function(__ref context, __attr target))(__attr[]);
    32.8 -__attr (*__check_and_get_function(__ref context, __attr target))(__attr[]);
    32.9 +__attr (*__get_function(__ref context, __attr target))();
   32.10 +__attr (*__check_and_get_function(__ref context, __attr target))();
   32.11  
   32.12  /* Parameter position operations. */
   32.13  
    33.1 --- a/templates/progops.c	Mon Mar 06 22:29:36 2017 +0100
    33.2 +++ b/templates/progops.c	Tue Mar 07 00:28:18 2017 +0100
    33.3 @@ -24,6 +24,7 @@
    33.4  #include "progtypes.h"
    33.5  #include "main.h"
    33.6  #include "exceptions.h"
    33.7 +#include "calls.h"
    33.8  
    33.9  /* Generic instantiation operations, defining common members. */
   33.10  
   33.11 @@ -251,14 +252,19 @@
   33.12          }
   33.13      }
   33.14  
   33.15 -    /* Call with the prepared arguments. */
   33.16 +    /* Call with the prepared arguments via a special adaptor function that
   33.17 +       converts the array to an argument list. */
   33.18  
   33.19 -    return (always_callable ? __get_function(allargs[0].value, target) : __check_and_get_function(allargs[0].value, target))(allargs);
   33.20 +    return __call_with_args(
   33.21 +        always_callable ?
   33.22 +        __get_function(allargs[0].value, target) :
   33.23 +        __check_and_get_function(allargs[0].value, target),
   33.24 +        allargs, max);
   33.25  }
   33.26  
   33.27  /* Error routines. */
   33.28  
   33.29 -__attr __unbound_method(__attr args[])
   33.30 +__attr __unbound_method(__attr __self)
   33.31  {
   33.32      __attr excargs[1];
   33.33      __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs);
   33.34 @@ -280,10 +286,8 @@
   33.35  
   33.36  int __BOOL(__attr attr)
   33.37  {
   33.38 -    __attr args[2] = {__NULL, attr};
   33.39 -
   33.40      /* Invoke the bool function with the object and test against True. */
   33.41  
   33.42      return (attr.value == __builtins___boolean_True.value) ||
   33.43 -           (__fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value);
   33.44 +           (__fn___builtins___boolean_bool(__NULL, attr).value == __builtins___boolean_True.value);
   33.45  }
    34.1 --- a/templates/progops.h	Mon Mar 06 22:29:36 2017 +0100
    34.2 +++ b/templates/progops.h	Tue Mar 07 00:28:18 2017 +0100
    34.3 @@ -60,12 +60,12 @@
    34.4  /* Generic invocation operations. */
    34.5  
    34.6  __attr __invoke(__attr callable, int always_callable,
    34.7 -                unsigned int nkwargs, __param kwcodes[], __attr kwargs[],
    34.8 -                unsigned int nargs, __attr args[]);
    34.9 +                   unsigned int nkwargs, __param kwcodes[], __attr kwargs[],
   34.10 +                   unsigned int nargs, __attr args[]);
   34.11  
   34.12  /* Error routines. */
   34.13  
   34.14 -__attr __unbound_method(__attr args[]);
   34.15 +__attr __unbound_method(__attr __self);
   34.16  
   34.17  /* Generic operations depending on specific program details. */
   34.18  
   34.19 @@ -78,6 +78,6 @@
   34.20  /* Convenience definitions. */
   34.21  
   34.22  #define __NEWINSTANCE(__CLS) __new(&__InstanceTable_##__CLS, &__CLS, sizeof(__obj_##__CLS))
   34.23 -#define __ISINSTANCE(__ATTR, __TYPE) __BOOL(__fn_native_introspection_isinstance((__attr[]) {__NULL, __ATTR, __TYPE}))
   34.24 +#define __ISINSTANCE(__ATTR, __TYPE) __BOOL(__fn_native_introspection_isinstance(__NULL, __ATTR, __TYPE))
   34.25  
   34.26  #endif /* __PROGOPS_H__ */
    35.1 --- a/translator.py	Mon Mar 06 22:29:36 2017 +0100
    35.2 +++ b/translator.py	Tue Mar 07 00:28:18 2017 +0100
    35.3 @@ -848,10 +848,7 @@
    35.4              # Produce an appropriate access to an attribute's value.
    35.5  
    35.6              parameters = self.importer.function_parameters.get(self.get_namespace_path())
    35.7 -            if parameters and name in parameters:
    35.8 -                name_to_value = "%s->value" % name
    35.9 -            else:
   35.10 -                name_to_value = "%s.value" % name
   35.11 +            name_to_value = "%s.value" % name
   35.12  
   35.13              # Write a test that raises a TypeError upon failure.
   35.14  
   35.15 @@ -1187,7 +1184,7 @@
   35.16  
   35.17          # Encode the arguments.
   35.18  
   35.19 -        argstr = "__ARGS(%s)" % ", ".join(args)
   35.20 +        argstr = ", ".join(args)
   35.21          kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0"
   35.22          kwcodestr = kwcodes and ("__KWARGS(%s)" % ", ".join(kwcodes)) or "0"
   35.23  
   35.24 @@ -1195,7 +1192,9 @@
   35.25          # the number of values.
   35.26  
   35.27          if literal_instantiation:
   35.28 -            argstr += ", %d" % (len(args) - 1)
   35.29 +            argstr = "__ARGS(%s), %d" % (argstr, len(args) - 1)
   35.30 +        elif instantiation:
   35.31 +            argstr = "__ARGS(%s)" % argstr
   35.32  
   35.33          # First, the invocation expression is presented.
   35.34  
   35.35 @@ -1249,7 +1248,7 @@
   35.36                  target_var,
   35.37                  self.always_callable and 1 or 0,
   35.38                  len(kwargs), kwcodestr, kwargstr,
   35.39 -                len(args), argstr))
   35.40 +                len(args), "__ARGS(%s)" % argstr))
   35.41              return InvocationResult(stages)
   35.42  
   35.43      def always_callable(self, refs):
   35.44 @@ -1390,7 +1389,7 @@
   35.45          # static namespace members. The reference should be configured to return
   35.46          # such names.
   35.47  
   35.48 -        return TrResolvedNameRef(n.name, ref, expr=expr, is_global=is_global, parameter=parameter, location=location)
   35.49 +        return TrResolvedNameRef(n.name, ref, expr=expr, is_global=is_global, location=location)
   35.50  
   35.51      def process_not_node(self, n):
   35.52  
   35.53 @@ -1761,7 +1760,8 @@
   35.54  
   35.55          "Start the function having the given 'name'."
   35.56  
   35.57 -        print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name)
   35.58 +        self.write_parameters(name)
   35.59 +
   35.60          print >>self.out, "{"
   35.61          self.indent += 1
   35.62  
   35.63 @@ -1787,7 +1787,6 @@
   35.64              names.sort()
   35.65              self.writeline("__attr %s;" % ", ".join(names))
   35.66  
   35.67 -        self.write_parameters(name)
   35.68          self.start_unit()
   35.69  
   35.70      def end_function(self, name):
   35.71 @@ -1797,6 +1796,30 @@
   35.72          self.end_unit(name)
   35.73          print >>self.out
   35.74  
   35.75 +    def write_parameters(self, name):
   35.76 +
   35.77 +        """
   35.78 +        For the function having the given 'name', write definitions of
   35.79 +        parameters found in the arguments array.
   35.80 +        """
   35.81 +
   35.82 +        # Generate any self reference.
   35.83 +
   35.84 +        l = []
   35.85 +
   35.86 +        if self.is_method(name):
   35.87 +            l.append("__attr self")
   35.88 +        else:
   35.89 +            l.append("__attr __self")
   35.90 +
   35.91 +        # Generate aliases for the parameters.
   35.92 +
   35.93 +        for parameter in self.importer.function_parameters[name]:
   35.94 +            l.append("__attr %s" % encode_path(parameter))
   35.95 +
   35.96 +        self.writeline("__attr %s(%s)" % (
   35.97 +            encode_function_pointer(name), ", ".join(l)))
   35.98 +
   35.99      def write_temporaries(self, name):
  35.100  
  35.101          "Write temporary storage employed by 'name'."
  35.102 @@ -1826,25 +1849,6 @@
  35.103          if name in module.exception_namespaces:
  35.104              self.writeline("__exc __tmp_exc;")
  35.105  
  35.106 -    def write_parameters(self, name):
  35.107 -
  35.108 -        """
  35.109 -        For the function having the given 'name', write definitions of
  35.110 -        parameters found in the arguments array.
  35.111 -        """
  35.112 -
  35.113 -        parameters = self.importer.function_parameters[name]
  35.114 -
  35.115 -        # Generate any self reference.
  35.116 -
  35.117 -        if self.is_method(name):
  35.118 -            self.writeline("__attr * const self = &__args[0];")
  35.119 -
  35.120 -        # Generate aliases for the parameters.
  35.121 -
  35.122 -        for i, parameter in enumerate(parameters):
  35.123 -            self.writeline("__attr * const %s = &__args[%d];" % (encode_path(parameter), i+1))
  35.124 -
  35.125      def start_if(self, first, test_ref):
  35.126          statement = "%sif" % (not first and "else " or "")
  35.127  
    36.1 --- a/transresults.py	Mon Mar 06 22:29:36 2017 +0100
    36.2 +++ b/transresults.py	Tue Mar 07 00:28:18 2017 +0100
    36.3 @@ -63,9 +63,8 @@
    36.4  
    36.5      "A reference to a name in the translation."
    36.6  
    36.7 -    def __init__(self, name, ref, expr=None, is_global=False, parameter=None, location=None):
    36.8 +    def __init__(self, name, ref, expr=None, is_global=False, location=None):
    36.9          ResolvedNameRef.__init__(self, name, ref, expr, is_global)
   36.10 -        self.parameter = parameter
   36.11          self.location = location
   36.12  
   36.13      def access_location(self):
   36.14 @@ -107,7 +106,7 @@
   36.15              # All other assignments involve the names as they were given.
   36.16  
   36.17              else:
   36.18 -                return "(%s%s) = %s" % (self.parameter and "*" or "", attrname, self.expr)
   36.19 +                return "%s = %s" % (attrname, self.expr)
   36.20  
   36.21          # Expressions.
   36.22  
   36.23 @@ -125,7 +124,7 @@
   36.24          # All other accesses involve the names as they were given.
   36.25  
   36.26          else:
   36.27 -            return "(%s%s)" % (self.parameter and "*" or "", attrname)
   36.28 +            return "(%s)" % attrname
   36.29  
   36.30  class TrConstantValueRef(ConstantValueRef):
   36.31