# HG changeset patch # User Paul Boddie # Date 1481296957 -3600 # Node ID 4cb3b47bd18fdd3d7f15ca1ecef8cd6211dfc90d # Parent c1e29f21858e36c728cde1bb9ef03351cc2f75f6 Split the native module into modules within a common native package. Split the native function implementations into several files corresponding to the native package modules. diff -r c1e29f21858e -r 4cb3b47bd18f generator.py --- a/generator.py Fri Dec 09 00:09:01 2016 +0100 +++ b/generator.py Fri Dec 09 16:22:37 2016 +0100 @@ -31,7 +31,7 @@ encode_symbol, encode_tablename, \ encode_type_attribute, decode_type_attribute, \ is_type_attribute -from os import listdir +from os import listdir, mkdir from os.path import exists, isdir, join, split from referencing import Reference @@ -111,7 +111,23 @@ if debug and exists(join(templates, "%s-debug" % filename)): continue - copy(join(templates, filename), target) + pathname = join(templates, filename) + + # Copy files into the target directory. + + if not isdir(pathname): + copy(pathname, target) + + # Copy directories (such as the native code directory). + + else: + target = join(self.output, filename) + + if not exists(target): + mkdir(target) + + for filename in listdir(pathname): + copy(join(pathname, filename), target) def write_structures(self): @@ -964,9 +980,11 @@ function_name = "__main_%s" % encode_path(name) print >>f_signatures, "void %s();" % function_name - # Omit the native module. + # Omit the native modules. - if name != "native": + parts = name.split(".") + + if parts[0] != "native": print >>f_code, """\ %s();""" % function_name diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/attribute.py --- a/lib/__builtins__/attribute.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/attribute.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _object_getattr +from native import object_getattr _default=object() # a unique placeholder for a missing value @@ -30,7 +30,7 @@ 'default' if the attribute is not defined for 'obj'. """ - return _object_getattr(obj, name, default) + return object_getattr(obj, name, default) def getattr(obj, name, default=_default): diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/buffer.py --- a/lib/__builtins__/buffer.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/buffer.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _list_init, _list_append, _list_concat, _buffer_str +from native import list_init, list_append, list_concat, buffer_str class buffer: @@ -36,7 +36,7 @@ else: raise TypeError(size) - self.__data__ = _list_init(n) + self.__data__ = list_init(n) # Append all arguments to the buffer. @@ -52,17 +52,17 @@ """ if isinstance(s, buffer): - _list_concat(self, s.__data__) + list_concat(self, s.__data__) elif isinstance(s, string): - _list_append(self, s) + list_append(self, s) else: - _list_append(self, str(s)) + list_append(self, str(s)) def __str__(self): "Return a string representation." - return _buffer_str(self.__data__) + return buffer_str(self.__data__) def __repr__(self): diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/character.py --- a/lib/__builtins__/character.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/character.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _str_ord +from native import str_ord def chr(i): pass def hex(number): pass @@ -30,7 +30,7 @@ "Return the value of the given character 'c'." if isinstance(c, string) and len(c) == 1: - return _str_ord(c.__data__) + return str_ord(c.__data__) else: raise ValueError(c) diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/core.py --- a/lib/__builtins__/core.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/core.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _get_using +from native import get_using class object: @@ -127,10 +127,4 @@ class Warning: pass class ZeroDivisionError(Exception): pass -def get_using(callable, instance): - - "Return 'callable' bound to 'instance'." - - return _get_using(callable, instance) - # vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/dict.py --- a/lib/__builtins__/dict.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/dict.py Fri Dec 09 16:22:37 2016 +0100 @@ -86,7 +86,7 @@ index = key.__hash__() - if not native._isinstance(index, int): + if not native.isinstance(index, int): raise TypeError return index % len(self.buckets) diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/file.py --- a/lib/__builtins__/file.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/file.py Fri Dec 09 16:22:37 2016 +0100 @@ -42,7 +42,7 @@ # Read any indicated number of bytes. if n > 0: - return native._fread(self.__data__, n) + return native.fread(self.__data__, n) # Read all remaining bytes. @@ -53,7 +53,7 @@ try: while True: - l.append(native._fread(self.__data__, self.bufsize)) + l.append(native.fread(self.__data__, self.bufsize)) # Handle end-of-file reads. @@ -67,13 +67,13 @@ "Write string 's' to the stream." check_string(s) - native._fwrite(self.__data__, s) + native.fwrite(self.__data__, s) def close(self): "Close the stream." - native._fclose(self.__data__) + native.fclose(self.__data__) class file(filestream): @@ -84,7 +84,7 @@ "Open the file with the given 'filename' using the given access 'mode'." get_using(filestream.__init__, self)(bufsize) - self.__data__ = native._fopen(filename, mode) + self.__data__ = native.fopen(filename, mode) def readline(self, size=None): pass def readlines(self, size=None): pass diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/identity.py --- a/lib/__builtins__/identity.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/identity.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _isinstance, _issubclass +import native def callable(obj): @@ -56,13 +56,13 @@ either a class or a sequence of classes. """ - if _isinstance(cls_or_tuple, tuple): + if native.isinstance(cls_or_tuple, tuple): for cls in cls_or_tuple: - if obj.__class__ is cls or isclass(cls) and _isinstance(obj, cls): + if obj.__class__ is cls or isclass(cls) and native.isinstance(obj, cls): return True return False else: - return obj.__class__ is cls_or_tuple or isclass(cls_or_tuple) and _isinstance(obj, cls_or_tuple) + return obj.__class__ is cls_or_tuple or isclass(cls_or_tuple) and native.isinstance(obj, cls_or_tuple) def issubclass(obj, cls_or_tuple): @@ -74,13 +74,13 @@ if not isclass(obj): return False - elif _isinstance(cls_or_tuple, tuple): + elif native.isinstance(cls_or_tuple, tuple): for cls in cls_or_tuple: - if obj is cls or isclass(cls) and _issubclass(obj, cls): + if obj is cls or isclass(cls) and native.issubclass(obj, cls): return True return False else: - return obj is cls_or_tuple or isclass(cls_or_tuple) and _issubclass(obj, cls_or_tuple) + return obj is cls_or_tuple or isclass(cls_or_tuple) and native.issubclass(obj, cls_or_tuple) def repr(obj): diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/int.py --- a/lib/__builtins__/int.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/int.py Fri Dec 09 16:22:37 2016 +0100 @@ -30,7 +30,7 @@ "Initialise the integer with the given 'number_or_string'." - if native._isinstance(number_or_string, int): + if native.isinstance(number_or_string, int): self.__data__ = number_or_string.__data__ else: # NOTE: To be implemented. @@ -46,7 +46,7 @@ "Perform 'op' on this int and 'other' if appropriate." - if native._isinstance(other, int): + if native.isinstance(other, int): return op(self.__data__, other.__data__) else: return NotImplemented @@ -55,7 +55,7 @@ "Perform 'op' on 'other' and this int if appropriate." - if native._isinstance(other, int): + if native.isinstance(other, int): return op(other.__data__, self.__data__) else: return NotImplemented @@ -64,61 +64,61 @@ "Return a new int for the addition of this int and 'other'." - return self._binary_op(native._int_add, other) + return self._binary_op(native.int_add, other) def __isub__(self, other): "Return a new int for the subtraction of this int and 'other'." - return self._binary_op(native._int_sub, other) + return self._binary_op(native.int_sub, other) def __imul__(self, other): "Return a new int for the multiplication of this int and 'other'." - return self._binary_op(native._int_mul, other) + return self._binary_op(native.int_mul, other) def __idiv__(self, other): "Return a new int for the division of this int and 'other'." - return self._binary_op(native._int_div, other) + return self._binary_op(native.int_div, other) def __imod__(self, other): "Return a new int for the modulo of this int by 'other'." - return self._binary_op(native._int_mod, other) + return self._binary_op(native.int_mod, other) def __ipow__(self, other): "Return a new int for the exponentiation of this int by 'other'." - return self._binary_op(native._int_pow, other) + return self._binary_op(native.int_pow, other) def __iand__(self, other): "Return a new int for the binary-and of this int and 'other'." - return self._binary_op(native._int_and, other) + return self._binary_op(native.int_and, other) def __ior__(self, other): "Return a new int for the binary-or of this int and 'other'." - return self._binary_op(native._int_or, other) + return self._binary_op(native.int_or, other) def __ixor__(self, other): "Return a new int for the exclusive-or of this int and 'other'." - return self._binary_op(native._int_xor, other) + return self._binary_op(native.int_xor, other) def __invert__(self): "Return the inversion of this int." - return native._int_not(self.__data__) + return native.int_not(self.__data__) __add__ = __radd__ = __iadd__ __sub__ = __isub__ @@ -127,7 +127,7 @@ "Return a new int for the subtraction of this int from 'other'." - return self._binary_op_rev(native._int_sub, other) + return self._binary_op_rev(native.int_sub, other) __mul__ = __rmul__ = __imul__ __div__ = __idiv__ @@ -136,7 +136,7 @@ "Return a new int for the division of this int into 'other'." - return self._binary_op_rev(native._int_div, other) + return self._binary_op_rev(native.int_div, other) def __floordiv__(self, other): pass def __rfloordiv__(self, other): pass @@ -148,7 +148,7 @@ "Return a new int for the modulo of 'other' by this int." - return self._binary_op_rev(native._int_mod, other) + return self._binary_op_rev(native.int_mod, other) __pow__ = __ipow__ @@ -156,7 +156,7 @@ "Return a new int for the exponentiation of 'other' by this int." - return self._binary_op_rev(native._int_pow, other) + return self._binary_op_rev(native.int_pow, other) __and__ = __rand__ = __iand__ __or__ = __ror__ = __ior__ @@ -166,13 +166,13 @@ "Return whether this int is less than 'other'." - return self._binary_op(native._int_lt, other) + return self._binary_op(native.int_lt, other) def __gt__(self, other): "Return whether this int is greater than 'other'." - return self._binary_op(native._int_gt, other) + return self._binary_op(native.int_gt, other) def __le__(self, other): @@ -190,7 +190,7 @@ "Return whether this int is equal to 'other'." - return self._binary_op(native._int_eq, other) + return self._binary_op(native.int_eq, other) def __ne__(self, other): @@ -202,7 +202,7 @@ "Apply the unary negation operator." - return native._int_neg(self.__data__) + return native.int_neg(self.__data__) def __pos__(self): @@ -214,7 +214,7 @@ "Return a string representation." - return native._int_str(self.__data__) + return native.int_str(self.__data__) __repr__ = __str__ @@ -230,11 +230,11 @@ "Return whether this int is non-zero." zero = 0 - return native._int_ne(self.__data__, zero.__data__) + return native.int_ne(self.__data__, zero.__data__) # Limits. -maxint = native._get_maxint() -minint = native._get_minint() +maxint = native.get_maxint() +minint = native.get_minint() # vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/list.py --- a/lib/__builtins__/list.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/list.py Fri Dec 09 16:22:37 2016 +0100 @@ -34,7 +34,7 @@ # Reserve an attribute for a fragment reference along with some space # for elements. - self.__data__ = native._list_init(args is not None and len(args) or 0) + self.__data__ = native.list_init(args is not None and len(args) or 0) if args is not None: self.extend(args) @@ -47,7 +47,7 @@ "Append 'value' to the list." - native._list_append(self, value) + native.list_append(self, value) def insert(self, i, value): pass @@ -66,7 +66,7 @@ "Return the length of the list." - return native._list_len(self.__data__) + return native.list_len(self.__data__) def __add__(self, other): pass @@ -75,7 +75,7 @@ "Concatenate 'other' to the list." if isinstance(other, list): - native._list_concat(self, other.__data__) + native.list_concat(self, other.__data__) else: self.extend(other) return self @@ -92,7 +92,7 @@ "Lists are true if non-empty." - return native._list_nonempty(self.__data__) + return native.list_nonempty(self.__data__) def __iter__(self): @@ -107,13 +107,13 @@ "Return the item at the normalised (positive) 'index'." self._check_index(index) - return native._list_element(self.__data__, index) + return native.list_element(self.__data__, index) def __set_single_item__(self, index, value): "Set at the normalised (positive) 'index' the given 'value'." self._check_index(index) - return native._list_setelement(self.__data__, index, value) + return native.list_setelement(self.__data__, index, value) # vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/sequence.py --- a/lib/__builtins__/sequence.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/sequence.py Fri Dec 09 16:22:37 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _isinstance +import native class itemaccess: @@ -42,13 +42,13 @@ # Normalise any integer indexes, converting negative indexes to positive # ones. - if _isinstance(index, int): + if native.isinstance(index, int): index = _get_absolute_index(index, self.__len__()) return self.__get_single_item__(index) # Handle slices separately. - elif _isinstance(index, slice): + elif native.isinstance(index, slice): return self.__getslice__(index.start, index.end, index.step) # No other kinds of objects are supported as indexes. @@ -63,13 +63,13 @@ # Normalise any integer indexes, converting negative indexes to positive # ones. - if _isinstance(index, int): + if native.isinstance(index, int): index = _get_absolute_index(index, self.__len__()) return self.__set_single_item__(index, value) # Handle slices separately. - elif _isinstance(index, slice): + elif native.isinstance(index, slice): return self.__setslice__(index.start, index.end, value) # No other kinds of objects are supported as indexes. diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/str.py --- a/lib/__builtins__/str.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/str.py Fri Dec 09 16:22:37 2016 +0100 @@ -68,7 +68,7 @@ "Return a string combining this string with 'other'." - return self._binary_op(native._str_add, other) + return self._binary_op(native.str_add, other) __add__ = __radd__ = __iadd__ @@ -81,13 +81,13 @@ "Return whether this string is less than 'other'." - return self._binary_op(native._str_lt, other) + return self._binary_op(native.str_lt, other) def __gt__(self, other): "Return whether this string is greater than 'other'." - return self._binary_op(native._str_gt, other) + return self._binary_op(native.str_gt, other) def __le__(self, other): @@ -105,7 +105,7 @@ "Return whether this string is equal to 'other'." - return self._binary_op(native._str_eq, other) + return self._binary_op(native.str_eq, other) def __ne__(self, other): @@ -117,7 +117,7 @@ "Return the length of this string." - return native._str_len(self.__data__) + return native.str_len(self.__data__) def __str__(self): @@ -134,7 +134,7 @@ return str(b) def __bool__(self): - return native._str_nonempty(self.__data__) + return native.str_nonempty(self.__data__) def endswith(self, s): pass def find(self, sub, start=None, end=None): pass @@ -182,7 +182,7 @@ "Return the item at the normalised (positive) 'index'." self._check_index(index) - return native._str_substr(self.__data__, index, 1) + return native.str_substr(self.__data__, index, 1) class string(basestring): pass diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/tuple.py --- a/lib/__builtins__/tuple.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/tuple.py Fri Dec 09 16:22:37 2016 +0100 @@ -35,15 +35,15 @@ # for elements. size = args is not None and len(args) or 0 - self.__data__ = native._list_init(size) - native._list_setsize(self.__data__, size) + self.__data__ = native.list_init(size) + native.list_setsize(self.__data__, size) # Populate the tuple. if args is not None: i = 0 for arg in args: - native._list_setelement(self.__data__, i, arg) + native.list_setelement(self.__data__, i, arg) i += 1 def __getslice__(self, start, end=None): @@ -56,7 +56,7 @@ "Return the length of the tuple." - return native._list_len(self.__data__) + return native.list_len(self.__data__) def __add__(self, other): pass @@ -87,7 +87,7 @@ "Return the item at the normalised (positive) 'index'." self._check_index(index) - return native._list_element(self.__data__, index) + return native.list_element(self.__data__, index) def __set_single_item__(self, index, value): diff -r c1e29f21858e -r 4cb3b47bd18f lib/__builtins__/types.py --- a/lib/__builtins__/types.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/__builtins__/types.py Fri Dec 09 16:22:37 2016 +0100 @@ -25,14 +25,14 @@ "Check the given int 'i'." - if not native._isinstance(i, int): + if not native.isinstance(i, int): raise ValueError(i) def check_string(s): "Check the given string 's'." - if not native._isinstance(s, string): + if not native.isinstance(s, string): raise ValueError(s) # vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native.py --- a/lib/native.py Fri Dec 09 00:09:01 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -""" -Native library functions. - -None of these are actually defined here. Instead, native implementations are -substituted when each program is built. It is, however, important to declare -non-core exceptions used by the native functions because they need to be -identified as being needed by the program. - -Copyright (C) 2011, 2015, 2016 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 -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -# Environment support. - -def _exit(status): pass -def _get_argv(): pass -def _get_path(): pass - -# Identity testing. - -def _is(x, y): pass -def _is_not(x, y): pass - -# Limit definition. - -def _get_maxint(): pass -def _get_minint(): pass - -# Integer operations. - -def _int_add(self, other): pass -def _int_div(self, other): pass -def _int_mod(self, other): pass -def _int_mul(self, other): pass -def _int_neg(self): pass -def _int_pow(self, other): pass -def _int_sub(self, other): pass - -def _int_and(self, other): pass -def _int_not(self): pass -def _int_or(self, other): pass -def _int_xor(self, other): pass - -def _int_lt(self, other): pass -def _int_gt(self, other): pass -def _int_eq(self, other): pass -def _int_ne(self, other): pass - -def _int_str(self): pass - -# String operations. - -def _str_add(self, other): pass -def _str_eq(self, other): pass -def _str_gt(self, other): pass -def _str_lt(self, other): pass -def _str_len(self): pass -def _str_nonempty(self): pass -def _str_ord(self): pass -def _str_substr(self, start, size): pass - -# List operations. - -def _list_init(size): pass -def _list_setsize(self, size): pass -def _list_append(self, value): pass -def _list_concat(self, other): pass -def _list_len(self): pass -def _list_nonempty(self): pass -def _list_element(self, index): pass -def _list_setelement(self, index, value): pass - -# Buffer operations. - -def _buffer_str(self): pass - -# Method binding. - -def _get_using(callable, instance): pass - -# Introspection. - -def _object_getattr(obj, name, default): pass -def _isinstance(obj, cls): pass -def _issubclass(obj, cls): pass - -# Input/output. - -def _fclose(fp): IOError -def _fopen(filename, mode): IOError -def _fdopen(fd, mode): IOError -def _close(fd): IOError -def _read(fd, n): IOError -def _write(fd, str): IOError - -def _fread(fp, n): - IOError - EOFError - -def _fwrite(fp, str): - IOError - EOFError - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/__init__.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +""" +Native library functions. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from native.buffer import buffer_str + +from native.identity import is_, is_not + +from native.int import int_add, int_div, int_mod, int_mul, int_neg, int_pow, \ + int_sub, int_and, int_not, int_or, int_xor, int_lt, \ + int_gt, int_eq, int_ne, int_str + +from native.introspection import object_getattr, isinstance, issubclass + +from native.io import fclose, fopen, fdopen, close, read, write, fread, fwrite + +from native.limits import get_maxint, get_minint + +from native.list import list_init, list_setsize, list_append, list_concat, \ + list_len, list_nonempty, list_element, list_setelement + +from native.program import get_using + +from native.str import str_add, str_eq, str_gt, str_lt, str_len, str_nonempty, \ + str_ord, str_substr + +from native.system import exit, get_argv, get_path + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/buffer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/buffer.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +""" +Native library functions for buffers. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def buffer_str(self): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/identity.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/identity.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +""" +Native library functions for identity testing. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def is_(x, y): pass +def is_not(x, y): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/int.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/int.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +""" +Native library functions for integers. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def int_add(self, other): pass +def int_div(self, other): pass +def int_mod(self, other): pass +def int_mul(self, other): pass +def int_neg(self): pass +def int_pow(self, other): pass +def int_sub(self, other): pass + +def int_and(self, other): pass +def int_not(self): pass +def int_or(self, other): pass +def int_xor(self, other): pass + +def int_lt(self, other): pass +def int_gt(self, other): pass +def int_eq(self, other): pass +def int_ne(self, other): pass + +def int_str(self): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/introspection.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/introspection.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +""" +Native library functions for introspection. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def object_getattr(obj, name, default): pass +def isinstance(obj, cls): pass +def issubclass(obj, cls): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/io.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/io.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +""" +Native library functions for input/output. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def fclose(fp): IOError +def fopen(filename, mode): IOError +def fdopen(fd, mode): IOError +def close(fd): IOError +def read(fd, n): IOError +def write(fd, str): IOError + +def fread(fp, n): + IOError + EOFError + +def fwrite(fp, str): + IOError + EOFError + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/limits.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/limits.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +""" +Native library functions for value limits. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def get_maxint(): pass +def get_minint(): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/list.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/list.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +""" +Native library functions for lists. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def list_init(size): pass +def list_setsize(self, size): pass +def list_append(self, value): pass +def list_concat(self, other): pass +def list_len(self): pass +def list_nonempty(self): pass +def list_element(self, index): pass +def list_setelement(self, index, value): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/program.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/program.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +""" +Native library functions for program operations. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +# Method binding. + +def get_using(callable, instance): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/str.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/str.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +Native library functions for strings. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +# String operations. + +def str_add(self, other): pass +def str_eq(self, other): pass +def str_gt(self, other): pass +def str_lt(self, other): pass +def str_len(self): pass +def str_nonempty(self): pass +def str_ord(self): pass +def str_substr(self, start, size): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/native/system.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/native/system.py Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +""" +Native library functions for system operations. + +None of these are actually defined here. Instead, native implementations are +substituted when each program is built. It is, however, important to declare +non-core exceptions used by the native functions because they need to be +identified as being needed by the program. + +Copyright (C) 2011, 2015, 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +def exit(status): pass +def get_argv(): pass +def get_path(): pass + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f lib/operator/core.py --- a/lib/operator/core.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/operator/core.py Fri Dec 09 16:22:37 2016 +0100 @@ -22,7 +22,7 @@ # Define "is" and "is not" in terms of native operations. They are imported by # the operator.binary module. -from native import _is as is_, _is_not as is_not +from native import is_, is_not def binary_op(a, b, left_accessor, right_accessor, default=None): diff -r c1e29f21858e -r 4cb3b47bd18f lib/posix/io.py --- a/lib/posix/io.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/posix/io.py Fri Dec 09 16:22:37 2016 +0100 @@ -78,7 +78,7 @@ "Close the file descriptor 'fd'." - native._close(fd) + native.close(fd) def closerange(fd_low, fd_high): pass def dup(fd): pass @@ -97,7 +97,7 @@ check_int(fd) check_string(mode) - return native._fdopen(fd, mode) + return native.fdopen(fd, mode) def fpathconf(fd, name): pass def fstat(fd): pass @@ -124,7 +124,7 @@ check_int(fd) check_int(n) - return native._read(fd, n) + return native.read(fd, n) def times(): pass def ttyname(fd): pass @@ -138,7 +138,7 @@ check_int(fd) check_string(s) - return native._write(fd, s) + return native.write(fd, s) # Constants. diff -r c1e29f21858e -r 4cb3b47bd18f lib/sys.py --- a/lib/sys.py Fri Dec 09 00:09:01 2016 +0100 +++ b/lib/sys.py Fri Dec 09 16:22:37 2016 +0100 @@ -25,12 +25,12 @@ # NOTE: Environment details to be implemented. -argv = native._get_argv() -path = native._get_path() +argv = native.get_argv() +path = native.get_path() # Functions to be implemented natively. def exit(status=0): - native._exit(int(status)) + native.exit(int(status)) # vim: tabstop=4 expandtab shiftwidth=4 diff -r c1e29f21858e -r 4cb3b47bd18f templates/Makefile --- a/templates/Makefile Fri Dec 09 00:09:01 2016 +0100 +++ b/templates/Makefile Fri Dec 09 16:22:37 2016 +0100 @@ -1,4 +1,4 @@ -SRC = exceptions.c main.c native.c ops.c progops.c progtypes.c $(wildcard src/*.c) +SRC = exceptions.c main.c $(wildcard native/*.c) ops.c progops.c progtypes.c $(wildcard src/*.c) OBJ = $(SRC:.c=.o) CFLAGS = -I. LDFLAGS = -lm diff -r c1e29f21858e -r 4cb3b47bd18f templates/Makefile-debug --- a/templates/Makefile-debug Fri Dec 09 00:09:01 2016 +0100 +++ b/templates/Makefile-debug Fri Dec 09 16:22:37 2016 +0100 @@ -1,4 +1,4 @@ -SRC = exceptions.c main.c native.c ops.c progops.c progtypes.c $(wildcard src/*.c) +SRC = exceptions.c main.c $(wildcard native/*.c) ops.c progops.c progtypes.c $(wildcard src/*.c) OBJ = $(SRC:.c=.o) CFLAGS = -I. -g LDFLAGS = -lm diff -r c1e29f21858e -r 4cb3b47bd18f templates/native.c --- a/templates/native.c Fri Dec 09 00:09:01 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,868 +0,0 @@ -/* Native functions. - -Copyright (C) 2016 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 -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -*/ - -#include /* abs, exit */ -#include /* read, write */ -#include /* INT_MAX, INT_MIN */ -#include /* ceil, log10, pow */ -#include /* strcmp, strncpy, strlen */ -#include /* fdopen, snprintf */ -#include /* errno */ -#include "types.h" -#include "exceptions.h" -#include "ops.h" -#include "progconsts.h" -#include "progops.h" -#include "progtypes.h" -#include "main.h" - -/* Utility functions. */ - -static __attr __new_int(int i) -{ - /* Create a new integer and mutate the __data__ attribute. */ - __attr attr = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int)); - attr.value->attrs[__pos___data__].intvalue = i; - return attr; -} - -static __attr __new_str(char *s) -{ - /* Create a new string and mutate the __data__ attribute. */ - __attr attr = __new(&__InstanceTable___builtins___str_string, &__builtins___str_string, sizeof(__obj___builtins___str_string)); - attr.value->attrs[__pos___data__].strvalue = s; - return attr; -} - -static __attr __new_list(__fragment *f) -{ - /* Create a new list and mutate the __data__ attribute. */ - __attr attr = __new(&__InstanceTable___builtins___list_list, &__builtins___list_list, sizeof(__obj___builtins___list_list)); - attr.value->attrs[__pos___data__].seqvalue = f; - return attr; -} - -static __fragment *__fragment_append(__fragment *data, __attr * const value) -{ - __fragment *newdata = data; - unsigned int size = data->size, capacity = data->capacity; - unsigned int n; - - /* Re-allocate the fragment if the capacity has been reached. */ - if (size >= capacity) - { - /* NOTE: Consider various restrictions on capacity increases. */ - n = capacity ? capacity * 2 : 1; - newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); - newdata->capacity = n; - } - - /* Insert the new element and increment the list size. */ - newdata->attrs[size] = *value; - newdata->size = size + 1; - - return newdata; -} - -/* Environment support. */ - -__attr __fn_native__exit(__attr __args[]) -{ - __attr * const status = &__args[1]; - - exit(__load_via_object(status->value, __pos___data__).intvalue); - return __builtins___none_None; -} - -__attr __fn_native__get_argv(__attr __args[]) -{ - __attr * const status = &__args[1]; - - /* NOTE: To be written. */ - return __builtins___none_None; -} - -__attr __fn_native__get_path(__attr __args[]) -{ - __attr * const status = &__args[1]; - - /* NOTE: To be written. */ - return __builtins___none_None; -} - -/* Identity testing. */ - -__attr __fn_native__is(__attr __args[]) -{ - __attr * const x = &__args[1]; - __attr * const y = &__args[2]; - - return x->value == y->value ? __builtins___boolean_True : __builtins___boolean_False; -} - -__attr __fn_native__is_not(__attr __args[]) -{ - __attr * const x = &__args[1]; - __attr * const y = &__args[2]; - - return x->value != y->value ? __builtins___boolean_True : __builtins___boolean_False; -} - -/* Limit definition. */ - -__attr __fn_native__get_maxint(__attr __args[]) -{ - __attr * const status = &__args[1]; - - return __new_int(INT_MAX); -} - -__attr __fn_native__get_minint(__attr __args[]) -{ - __attr * const status = &__args[1]; - - return __new_int(INT_MIN); -} - -/* Integer operations. */ - -__attr __fn_native__int_add(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - - /* Test for overflow. */ - if (((i > 0) && (j > 0) && (i > INT_MAX - j)) || - ((i < 0) && (j < 0) && (i < INT_MIN - j))) - - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(i + j); -} - -__attr __fn_native__int_sub(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - - /* Test for overflow. */ - if (((i < 0) && (j > 0) && (i < INT_MIN + j)) || - ((i > 0) && (j < 0) && (i > INT_MAX + j))) - - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(i - j); -} - -__attr __fn_native__int_mul(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - - /* Test for overflow. */ - if (((i > 0) && (j > 0) && (i > INT_MAX / j)) || - ((i < 0) && (j < 0) && (i > INT_MAX / j)) || - ((i < 0) && (j > 0) && (i < INT_MIN / j)) || - ((i > 0) && (j < 0) && (j < INT_MIN / i))) - - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(i * j); -} - -__attr __fn_native__int_div(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - - /* Test for division by zero or overflow. */ - if (j == 0) - __raise_zero_division_error(); - else if ((j == -1) && (i == INT_MIN)) - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(i / j); -} - -__attr __fn_native__int_mod(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - - /* Test for division by zero or overflow. */ - if (j == 0) - __raise_zero_division_error(); - else if ((j == -1) && (i == INT_MIN)) - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(i % j); -} - -__attr __fn_native__int_neg(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; - - /* Test for overflow. */ - if (i == INT_MIN) - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(-i); -} - -__attr __fn_native__int_pow(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - int i = _data->intvalue; - int j = other->intvalue; - int k; - - errno = 0; - k = (int) pow(i, j); - - /* Test for overflow. */ - - if (errno == ERANGE) - __raise_overflow_error(); - - /* Return the new integer. */ - return __new_int(k); -} - -__attr __fn_native__int_and(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_not(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - int i = _data->intvalue; - - /* Return the new integer. */ - return __new_int(~i); -} - -__attr __fn_native__int_or(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_xor(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_lt(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_gt(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_eq(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_ne(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data and other interpreted as int */ - 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_str(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as int */ - 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; - char *s = (char *) __ALLOCATE(n, sizeof(char)); - - snprintf(s, n, "%d", i); - - /* Return a new string. */ - return __new_str(s); -} - -/* String operations. */ - -__attr __fn_native__str_add(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - char *s = _data->strvalue; - char *o = other->strvalue; - int n = strlen(s) + strlen(o) + 1; - char *r = (char *) __ALLOCATE(n, sizeof(char)); - - strncpy(r, s, n); - strncpy(r + strlen(s), o, n - strlen(s)); /* should null terminate */ - - /* Return a new string. */ - return __new_str(r); -} - -__attr __fn_native__str_lt(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - 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_gt(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - 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_eq(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const other = &__args[2]; - /* _data, other interpreted as string */ - 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_len(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as string */ - char *s = _data->strvalue; - - /* Return the new integer. */ - return __new_int(strlen(s)); -} - -__attr __fn_native__str_nonempty(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as string */ - char *s = _data->strvalue; - - return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; -} - -__attr __fn_native__str_ord(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as string */ - char *s = _data->strvalue; - - return __new_int((unsigned int) s[0]); -} - -__attr __fn_native__str_substr(__attr __args[]) -{ - __attr * const _data = &__args[1]; - __attr * const start = &__args[2]; - __attr * const size = &__args[3]; - /* _data interpreted as string */ - char *s = _data->strvalue, *sub; - /* start.__data__ interpreted as int */ - int i = __load_via_object(start->value, __pos___data__).intvalue; - /* size.__data__ interpreted as int */ - int l = __load_via_object(size->value, __pos___data__).intvalue; - - /* Reserve space for a new string. */ - sub = (char *) __ALLOCATE(l + 1, sizeof(char)); - strncpy(sub, s + i, l); /* does not null terminate but final byte should be zero */ - return __new_str(sub); -} - -/* List operations. */ - -__attr __fn_native__list_init(__attr __args[]) -{ - __attr * const size = &__args[1]; - /* size.__data__ interpreted as int */ - unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; - __attr attr = {0, .seqvalue=__new_fragment(n)}; - - /* Return the __data__ attribute. */ - return attr; -} - -__attr __fn_native__list_setsize(__attr __args[]) -{ - __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, __pos___data__).intvalue; - - data->size = n; - return __builtins___none_None; -} - -__attr __fn_native__list_append(__attr __args[]) -{ - __attr * const self = &__args[1]; - __attr * const value = &__args[2]; - /* self.__data__ interpreted as list */ - __fragment *data = __load_via_object(self->value, __pos___data__).seqvalue; - __fragment *newdata = __fragment_append(data, value); - - /* Replace the __data__ attribute if appropriate. */ - if (newdata != data) - __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); - return __builtins___none_None; -} - -__attr __fn_native__list_concat(__attr __args[]) -{ - __attr * const self = &__args[1]; - __attr * const other = &__args[2]; - /* self.__data__, other interpreted as list */ - __fragment *data = __load_via_object(self->value, __pos___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; - unsigned int i, j, n; - - /* Re-allocate the fragment if the capacity has been reached. */ - if (size + other_size >= capacity) - { - n = size + other_size; - newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); - newdata->capacity = n; - } - - /* Copy the elements from the other list and increment the list size. */ - for (i = size, j = 0; j < other_size; i++, j++) - newdata->attrs[i] = other_data->attrs[j]; - newdata->size = n; - - /* Replace the __data__ attribute if appropriate. */ - if (newdata != data) - __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); - return __builtins___none_None; -} - -__attr __fn_native__list_len(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as fragment */ - unsigned int size = _data->seqvalue->size; - - /* Return the new integer. */ - return __new_int(size); -} - -__attr __fn_native__list_nonempty(__attr __args[]) -{ - __attr * const _data = &__args[1]; - - return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; -} - -__attr __fn_native__list_element(__attr __args[]) -{ - __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, __pos___data__).intvalue; - - return elements[i]; -} - -__attr __fn_native__list_setelement(__attr __args[]) -{ - __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, __pos___data__).intvalue; - - /* Set the element. */ - elements[i] = *value; - return __builtins___none_None; -} - -/* Buffer operations. */ - -__attr __fn_native__buffer_str(__attr __args[]) -{ - __attr * const _data = &__args[1]; - /* _data interpreted as buffer */ - __fragment *data = _data->seqvalue; - unsigned int size = 0, i, j, n; - char *s, *o; - - /* Calculate the size of the string. */ - for (i = 0; i < data->size; i++) - size += strlen(__load_via_object(data->attrs[i].value, __pos___data__).strvalue); - - /* Reserve space for a new string. */ - s = (char *) __ALLOCATE(size + 1, sizeof(char)); - - /* Build a single string from the buffer contents. */ - for (i = 0, j = 0; i < data->size; i++) - { - o = __load_via_object(data->attrs[i].value, __pos___data__).strvalue; - n = strlen(o); - strncpy(s + j, o, n); /* does not null terminate but final byte should be zero */ - j += n; - } - - /* Return a new string. */ - return __new_str(s); -} - -/* Method binding. */ - -__attr __fn_native__get_using(__attr __args[]) -{ - __attr * const callable = &__args[1]; - __attr * const instance = &__args[2]; - - return __replace_context(instance->value, *callable); -} - -/* Introspection. */ - -__attr __fn_native__object_getattr(__attr __args[]) -{ - __attr * const obj = &__args[1]; - __attr * const name = &__args[2]; - __attr * const _default = &__args[3]; - - /* NOTE: To be written. */ - return __builtins___none_None; -} - -static int __issubclass(__ref obj, __attr cls) -{ - return (__HASATTR(obj, __TYPEPOS(cls.value), __TYPECODE(cls.value))); -} - -__attr __fn_native__isinstance(__attr __args[]) -{ - __attr * const obj = &__args[1]; - __attr * const cls = &__args[2]; - - /* cls must be a class. */ - if (__is_instance(obj->value) && __issubclass(__get_class(obj->value), *cls)) - return __builtins___boolean_True; - else - return __builtins___boolean_False; -} - -__attr __fn_native__issubclass(__attr __args[]) -{ - __attr * const obj = &__args[1]; - __attr * const cls = &__args[2]; - - /* obj and cls must be classes. */ - if (__issubclass(obj->value, *cls)) - return __builtins___boolean_True; - else - return __builtins___boolean_False; -} - -/* Input/output. */ - -__attr __fn_native__fclose(__attr __args[]) -{ - __attr * const fp = &__args[1]; - /* fp interpreted as FILE reference */ - FILE *f = (FILE *) fp->datavalue; - - errno = 0; - if (fclose(f)) - __raise_io_error(__new_int(errno)); - - return __builtins___none_None; -} - -__attr __fn_native__fopen(__attr __args[]) -{ - __attr * const filename = &__args[1]; - __attr * const mode = &__args[2]; - /* filename.__data__ interpreted as string */ - char *fn = __load_via_object(filename->value, __pos___data__).strvalue; - /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __pos___data__).strvalue; - FILE *f; - __attr attr; - - errno = 0; - f = fopen(fn, s); - - /* Produce an exception if the operation failed. */ - - if (f == NULL) - __raise_io_error(__new_int(errno)); - - /* Return the __data__ attribute. */ - - else - { - attr.context = 0; - attr.datavalue = (void *) f; - return attr; - } -} - -__attr __fn_native__fdopen(__attr __args[]) -{ - __attr * const fd = &__args[1]; - __attr * const mode = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __pos___data__).intvalue; - /* mode.__data__ interpreted as string */ - char *s = __load_via_object(mode->value, __pos___data__).strvalue; - FILE *f; - __attr attr; - - errno = 0; - f = fdopen(i, s); - - /* Produce an exception if the operation failed. */ - - if (f == NULL) - __raise_io_error(__new_int(errno)); - - /* Return the __data__ attribute. */ - - else - { - attr.context = 0; - attr.datavalue = (void *) f; - return attr; - } -} - -__attr __fn_native__fread(__attr __args[]) -{ - __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, __pos___data__).intvalue; - char buf[to_read]; - size_t have_read; - int error; - char *s; - - have_read = fread(buf, sizeof(char), to_read, f); - - if (have_read != to_read) - { - if (feof(f) && (have_read == 0)) - __raise_eof_error(); - else if (error = ferror(f)) - __raise_io_error(__new_int(error)); - } - - /* Reserve space for a new string. */ - - s = __ALLOCATE(have_read + 1, sizeof(char)); - strncpy(s, (char *) buf, have_read); /* does not null terminate but final byte should be zero */ - return __new_str(s); -} - -__attr __fn_native__fwrite(__attr __args[]) -{ - __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, __pos___data__).strvalue; - size_t to_write = strlen(s); - size_t have_written = fwrite(s, sizeof(char), to_write, f); - int error; - - if (have_written != to_write) - { - if (feof(f)) - __raise_eof_error(); - else if (error = ferror(f)) - __raise_io_error(__new_int(error)); - } - - return __builtins___none_None; -} - -__attr __fn_native__close(__attr __args[]) -{ - __attr * const fd = &__args[1]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __pos___data__).intvalue; - - errno = 0; - if (close(i) == -1) - __raise_io_error(__new_int(errno)); - - return __builtins___none_None; -} - -__attr __fn_native__read(__attr __args[]) -{ - __attr * const fd = &__args[1]; - __attr * const n = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __pos___data__).intvalue; - /* n.__data__ interpreted as int */ - int to_read = __load_via_object(n->value, __pos___data__).intvalue; - char buf[to_read]; - ssize_t have_read; - char *s; - - errno = 0; - have_read = read(i, buf, to_read * sizeof(char)); - - if (have_read == -1) - __raise_io_error(__new_int(errno)); - - /* Reserve space for a new string. */ - - s = __ALLOCATE(have_read + 1, 1); - strncpy(s, (char *) buf, have_read); /* does not null terminate but final byte should be zero */ - return __new_str(s); -} - -__attr __fn_native__write(__attr __args[]) -{ - __attr * const fd = &__args[1]; - __attr * const str = &__args[2]; - /* fd.__data__ interpreted as int */ - int i = __load_via_object(fd->value, __pos___data__).intvalue; - /* str.__data__ interpreted as string */ - char *s = __load_via_object(str->value, __pos___data__).strvalue; - ssize_t have_written; - - errno = 0; - have_written = write(i, s, sizeof(char) * strlen(s)); - - if (have_written == -1) - __raise_io_error(__new_int(errno)); - - return __new_int(have_written); -} - -/* Module initialisation. */ - -void __main_native() -{ -} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native.h --- a/templates/native.h Fri Dec 09 00:09:01 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* Native functions. - -Copyright (C) 2016 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 -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -*/ - -#ifndef __NATIVE_H__ -#define __NATIVE_H__ - -/* Environment support. */ - -__attr __fn_native__exit(__attr __args[]); -__attr __fn_native__get_argv(__attr __args[]); -__attr __fn_native__get_path(__attr __args[]); - -/* Identity testing. */ - -__attr __fn_native__is(__attr __args[]); -__attr __fn_native__is_not(__attr __args[]); - -/* Limit definition. */ - -__attr __fn_native__get_maxint(__attr __args[]); -__attr __fn_native__get_minint(__attr __args[]); - -/* Integer operations. */ - -__attr __fn_native__int_add(__attr __args[]); -__attr __fn_native__int_div(__attr __args[]); -__attr __fn_native__int_mod(__attr __args[]); -__attr __fn_native__int_mul(__attr __args[]); -__attr __fn_native__int_neg(__attr __args[]); -__attr __fn_native__int_pow(__attr __args[]); -__attr __fn_native__int_sub(__attr __args[]); - -__attr __fn_native__int_and(__attr __args[]); -__attr __fn_native__int_not(__attr __args[]); -__attr __fn_native__int_or(__attr __args[]); -__attr __fn_native__int_xor(__attr __args[]); - -__attr __fn_native__int_rdiv(__attr __args[]); -__attr __fn_native__int_rmod(__attr __args[]); -__attr __fn_native__int_rpow(__attr __args[]); -__attr __fn_native__int_rsub(__attr __args[]); - -__attr __fn_native__int_lt(__attr __args[]); -__attr __fn_native__int_gt(__attr __args[]); -__attr __fn_native__int_eq(__attr __args[]); -__attr __fn_native__int_ne(__attr __args[]); - -__attr __fn_native__int_str(__attr __args[]); - -/* String operations. */ - -__attr __fn_native__str_add(__attr __args[]); -__attr __fn_native__str_lt(__attr __args[]); -__attr __fn_native__str_gt(__attr __args[]); -__attr __fn_native__str_eq(__attr __args[]); -__attr __fn_native__str_len(__attr __args[]); -__attr __fn_native__str_nonempty(__attr __args[]); -__attr __fn_native__str_ord(__attr __args[]); -__attr __fn_native__str_substr(__attr __args[]); - -/* List operations. */ - -__attr __fn_native__list_init(__attr __args[]); -__attr __fn_native__list_setsize(__attr __args[]); -__attr __fn_native__list_append(__attr __args[]); -__attr __fn_native__list_concat(__attr __args[]); -__attr __fn_native__list_len(__attr __args[]); -__attr __fn_native__list_nonempty(__attr __args[]); -__attr __fn_native__list_element(__attr __args[]); -__attr __fn_native__list_setelement(__attr __args[]); - -/* Buffer operations. */ - -__attr __fn_native__buffer_str(__attr __args[]); - -/* Method binding. */ - -__attr __fn_native__get_using(__attr __args[]); - -/* Introspection. */ - -__attr __fn_native__object_getattr(__attr __args[]); -__attr __fn_native__isinstance(__attr __args[]); -__attr __fn_native__issubclass(__attr __args[]); - -/* Input/output. */ - -__attr __fn_native__fclose(__attr __args[]); -__attr __fn_native__fopen(__attr __args[]); -__attr __fn_native__fdopen(__attr __args[]); -__attr __fn_native__fread(__attr __args[]); -__attr __fn_native__fwrite(__attr __args[]); -__attr __fn_native__close(__attr __args[]); -__attr __fn_native__read(__attr __args[]); -__attr __fn_native__write(__attr __args[]); - -/* Module initialisation. */ - -void __main_native(); - -#endif /* __NATIVE_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/buffer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/buffer.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,61 @@ +/* Native functions for buffer operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* strcmp, strncpy, strlen */ +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +__attr __fn_native_buffer_buffer_str(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as buffer */ + __fragment *data = _data->seqvalue; + unsigned int size = 0, i, j, n; + char *s, *o; + + /* Calculate the size of the string. */ + for (i = 0; i < data->size; i++) + size += strlen(__load_via_object(data->attrs[i].value, __pos___data__).strvalue); + + /* Reserve space for a new string. */ + s = (char *) __ALLOCATE(size + 1, sizeof(char)); + + /* Build a single string from the buffer contents. */ + for (i = 0, j = 0; i < data->size; i++) + { + o = __load_via_object(data->attrs[i].value, __pos___data__).strvalue; + n = strlen(o); + strncpy(s + j, o, n); /* does not null terminate but final byte should be zero */ + j += n; + } + + /* Return a new string. */ + return __new_str(s); +} + +/* Module initialisation. */ + +void __main_native_buffer() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/buffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/buffer.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,32 @@ +/* Native functions for buffer operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_BUFFER_H__ +#define __NATIVE_BUFFER_H__ + +#include "types.h" + +/* Buffer operations. */ + +__attr __fn_native_buffer_buffer_str(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_buffer(); + +#endif /* __NATIVE_BUFFER_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/common.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,73 @@ +/* Common operations for native functions. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Utility functions. */ + +__attr __new_int(int i) +{ + /* Create a new integer and mutate the __data__ attribute. */ + __attr attr = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int)); + attr.value->attrs[__pos___data__].intvalue = i; + return attr; +} + +__attr __new_str(char *s) +{ + /* Create a new string and mutate the __data__ attribute. */ + __attr attr = __new(&__InstanceTable___builtins___str_string, &__builtins___str_string, sizeof(__obj___builtins___str_string)); + attr.value->attrs[__pos___data__].strvalue = s; + return attr; +} + +__attr __new_list(__fragment *f) +{ + /* Create a new list and mutate the __data__ attribute. */ + __attr attr = __new(&__InstanceTable___builtins___list_list, &__builtins___list_list, sizeof(__obj___builtins___list_list)); + attr.value->attrs[__pos___data__].seqvalue = f; + return attr; +} + +__fragment *__fragment_append(__fragment *data, __attr * const value) +{ + __fragment *newdata = data; + unsigned int size = data->size, capacity = data->capacity; + unsigned int n; + + /* Re-allocate the fragment if the capacity has been reached. */ + if (size >= capacity) + { + /* NOTE: Consider various restrictions on capacity increases. */ + n = capacity ? capacity * 2 : 1; + newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); + newdata->capacity = n; + } + + /* Insert the new element and increment the list size. */ + newdata->attrs[size] = *value; + newdata->size = size + 1; + + return newdata; +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/common.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,31 @@ +/* Common operations for native functions. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_COMMON_H__ +#define __NATIVE_COMMON_H__ + +#include "types.h" + +/* Utility functions. */ + +__attr __new_int(int i); +__attr __new_str(char *s); +__attr __new_list(__fragment *f); +__fragment *__fragment_append(__fragment *data, __attr * const value); + +#endif /* __NATIVE_COMMON_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/identity.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/identity.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,49 @@ +/* Native functions for identity operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Identity testing. */ + +__attr __fn_native_identity_is_(__attr __args[]) +{ + __attr * const x = &__args[1]; + __attr * const y = &__args[2]; + + return x->value == y->value ? __builtins___boolean_True : __builtins___boolean_False; +} + +__attr __fn_native_identity_is_not(__attr __args[]) +{ + __attr * const x = &__args[1]; + __attr * const y = &__args[2]; + + return x->value != y->value ? __builtins___boolean_True : __builtins___boolean_False; +} + +/* Module initialisation. */ + +void __main_native_identity() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/identity.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/identity.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,33 @@ +/* Native functions for identity operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_IDENTITY_H__ +#define __NATIVE_IDENTITY_H__ + +#include "types.h" + +/* Identity testing. */ + +__attr __fn_native_identity_is_(__attr __args[]); +__attr __fn_native_identity_is_not(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_identity(); + +#endif /* __NATIVE_IDENTITY_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/int.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/int.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,278 @@ +/* Native functions for integer operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* INT_MAX, INT_MIN */ +#include /* ceil, log10, pow */ +#include /* fdopen, snprintf */ +#include /* errno */ +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Integer operations. */ + +__attr __fn_native_int_int_add(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + + /* Test for overflow. */ + if (((i > 0) && (j > 0) && (i > INT_MAX - j)) || + ((i < 0) && (j < 0) && (i < INT_MIN - j))) + + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(i + j); +} + +__attr __fn_native_int_int_sub(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + + /* Test for overflow. */ + if (((i < 0) && (j > 0) && (i < INT_MIN + j)) || + ((i > 0) && (j < 0) && (i > INT_MAX + j))) + + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(i - j); +} + +__attr __fn_native_int_int_mul(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + + /* Test for overflow. */ + if (((i > 0) && (j > 0) && (i > INT_MAX / j)) || + ((i < 0) && (j < 0) && (i > INT_MAX / j)) || + ((i < 0) && (j > 0) && (i < INT_MIN / j)) || + ((i > 0) && (j < 0) && (j < INT_MIN / i))) + + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(i * j); +} + +__attr __fn_native_int_int_div(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + + /* Test for division by zero or overflow. */ + if (j == 0) + __raise_zero_division_error(); + else if ((j == -1) && (i == INT_MIN)) + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(i / j); +} + +__attr __fn_native_int_int_mod(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + + /* Test for division by zero or overflow. */ + if (j == 0) + __raise_zero_division_error(); + else if ((j == -1) && (i == INT_MIN)) + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(i % j); +} + +__attr __fn_native_int_int_neg(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as int */ + int i = _data->intvalue; + + /* Test for overflow. */ + if (i == INT_MIN) + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(-i); +} + +__attr __fn_native_int_int_pow(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + int i = _data->intvalue; + int j = other->intvalue; + int k; + + errno = 0; + k = (int) pow(i, j); + + /* Test for overflow. */ + + if (errno == ERANGE) + __raise_overflow_error(); + + /* Return the new integer. */ + return __new_int(k); +} + +__attr __fn_native_int_int_and(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + /* _data interpreted as int */ + int i = _data->intvalue; + + /* Return the new integer. */ + return __new_int(~i); +} + +__attr __fn_native_int_int_or(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data and other interpreted as int */ + 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 * const _data = &__args[1]; + /* _data interpreted as int */ + 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; + char *s = (char *) __ALLOCATE(n, sizeof(char)); + + snprintf(s, n, "%d", i); + + /* Return a new string. */ + return __new_str(s); +} + +/* Module initialisation. */ + +void __main_native_int() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/int.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/int.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,55 @@ +/* Native functions for integer operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_INT_H__ +#define __NATIVE_INT_H__ + +#include "types.h" + +/* Integer operations. */ + +__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_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_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 __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[]); + +/* Module initialisation. */ + +void __main_native_int(); + +#endif /* __NATIVE_INT_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/introspection.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/introspection.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,72 @@ +/* Native functions for introspection operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Introspection. */ + +__attr __fn_native_introspection_object_getattr(__attr __args[]) +{ + __attr * const obj = &__args[1]; + __attr * const name = &__args[2]; + __attr * const _default = &__args[3]; + + /* NOTE: To be written. */ + return __builtins___none_None; +} + +static int __issubclass(__ref obj, __attr cls) +{ + return (__HASATTR(obj, __TYPEPOS(cls.value), __TYPECODE(cls.value))); +} + +__attr __fn_native_introspection_isinstance(__attr __args[]) +{ + __attr * const obj = &__args[1]; + __attr * const cls = &__args[2]; + + /* cls must be a class. */ + if (__is_instance(obj->value) && __issubclass(__get_class(obj->value), *cls)) + return __builtins___boolean_True; + else + return __builtins___boolean_False; +} + +__attr __fn_native_introspection_issubclass(__attr __args[]) +{ + __attr * const obj = &__args[1]; + __attr * const cls = &__args[2]; + + /* obj and cls must be classes. */ + if (__issubclass(obj->value, *cls)) + return __builtins___boolean_True; + else + return __builtins___boolean_False; +} + +/* Module initialisation. */ + +void __main_native_introspection() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/introspection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/introspection.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,34 @@ +/* Native functions for introspection. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_INTROSPECTION_H__ +#define __NATIVE_INTROSPECTION_H__ + +#include "types.h" + +/* Introspection. */ + +__attr __fn_native_introspection_object_getattr(__attr __args[]); +__attr __fn_native_introspection_isinstance(__attr __args[]); +__attr __fn_native_introspection_issubclass(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_introspection(); + +#endif /* __NATIVE_INTROSPECTION_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/io.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/io.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,219 @@ +/* Native functions for input/output. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* read, write */ +#include /* strcmp, strncpy, strlen */ +#include /* fdopen, snprintf */ +#include /* errno */ +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Input/output. */ + +__attr __fn_native_io_fclose(__attr __args[]) +{ + __attr * const fp = &__args[1]; + /* fp interpreted as FILE reference */ + FILE *f = (FILE *) fp->datavalue; + + errno = 0; + if (fclose(f)) + __raise_io_error(__new_int(errno)); + + return __builtins___none_None; +} + +__attr __fn_native_io_fopen(__attr __args[]) +{ + __attr * const filename = &__args[1]; + __attr * const mode = &__args[2]; + /* filename.__data__ interpreted as string */ + char *fn = __load_via_object(filename->value, __pos___data__).strvalue; + /* mode.__data__ interpreted as string */ + char *s = __load_via_object(mode->value, __pos___data__).strvalue; + FILE *f; + __attr attr; + + errno = 0; + f = fopen(fn, s); + + /* Produce an exception if the operation failed. */ + + if (f == NULL) + __raise_io_error(__new_int(errno)); + + /* Return the __data__ attribute. */ + + else + { + attr.context = 0; + attr.datavalue = (void *) f; + return attr; + } +} + +__attr __fn_native_io_fdopen(__attr __args[]) +{ + __attr * const fd = &__args[1]; + __attr * const mode = &__args[2]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + /* mode.__data__ interpreted as string */ + char *s = __load_via_object(mode->value, __pos___data__).strvalue; + FILE *f; + __attr attr; + + errno = 0; + f = fdopen(i, s); + + /* Produce an exception if the operation failed. */ + + if (f == NULL) + __raise_io_error(__new_int(errno)); + + /* Return the __data__ attribute. */ + + else + { + attr.context = 0; + attr.datavalue = (void *) f; + return attr; + } +} + +__attr __fn_native_io_fread(__attr __args[]) +{ + __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, __pos___data__).intvalue; + char buf[to_read]; + size_t have_read; + int error; + char *s; + + have_read = fread(buf, sizeof(char), to_read, f); + + if (have_read != to_read) + { + if (feof(f) && (have_read == 0)) + __raise_eof_error(); + else if (error = ferror(f)) + __raise_io_error(__new_int(error)); + } + + /* Reserve space for a new string. */ + + s = __ALLOCATE(have_read + 1, sizeof(char)); + strncpy(s, (char *) buf, have_read); /* does not null terminate but final byte should be zero */ + return __new_str(s); +} + +__attr __fn_native_io_fwrite(__attr __args[]) +{ + __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, __pos___data__).strvalue; + size_t to_write = strlen(s); + size_t have_written = fwrite(s, sizeof(char), to_write, f); + int error; + + if (have_written != to_write) + { + if (feof(f)) + __raise_eof_error(); + else if (error = ferror(f)) + __raise_io_error(__new_int(error)); + } + + return __builtins___none_None; +} + +__attr __fn_native_io_close(__attr __args[]) +{ + __attr * const fd = &__args[1]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + + errno = 0; + if (close(i) == -1) + __raise_io_error(__new_int(errno)); + + return __builtins___none_None; +} + +__attr __fn_native_io_read(__attr __args[]) +{ + __attr * const fd = &__args[1]; + __attr * const n = &__args[2]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + /* n.__data__ interpreted as int */ + int to_read = __load_via_object(n->value, __pos___data__).intvalue; + char buf[to_read]; + ssize_t have_read; + char *s; + + errno = 0; + have_read = read(i, buf, to_read * sizeof(char)); + + if (have_read == -1) + __raise_io_error(__new_int(errno)); + + /* Reserve space for a new string. */ + + s = __ALLOCATE(have_read + 1, 1); + strncpy(s, (char *) buf, have_read); /* does not null terminate but final byte should be zero */ + return __new_str(s); +} + +__attr __fn_native_io_write(__attr __args[]) +{ + __attr * const fd = &__args[1]; + __attr * const str = &__args[2]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + /* str.__data__ interpreted as string */ + char *s = __load_via_object(str->value, __pos___data__).strvalue; + ssize_t have_written; + + errno = 0; + have_written = write(i, s, sizeof(char) * strlen(s)); + + if (have_written == -1) + __raise_io_error(__new_int(errno)); + + return __new_int(have_written); +} + +/* Module initialisation. */ + +void __main_native_io() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/io.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/io.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,39 @@ +/* Native functions for input/output. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_IO_H__ +#define __NATIVE_IO_H__ + +#include "types.h" + +/* Input/output. */ + +__attr __fn_native_io_fclose(__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[]); + +/* Module initialisation. */ + +void __main_native_io(); + +#endif /* __NATIVE_IO_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/limits.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/limits.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,49 @@ +/* Native functions for limit definition. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* INT_MAX, INT_MIN */ +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Limit definition. */ + +__attr __fn_native_limits_get_maxint(__attr __args[]) +{ + __attr * const status = &__args[1]; + + return __new_int(INT_MAX); +} + +__attr __fn_native_limits_get_minint(__attr __args[]) +{ + __attr * const status = &__args[1]; + + return __new_int(INT_MIN); +} + +/* Module initialisation. */ + +void __main_native_limits() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/limits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/limits.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,33 @@ +/* Native functions for limit definition. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_LIMITS_H__ +#define __NATIVE_LIMITS_H__ + +#include "types.h" + +/* Limit definition. */ + +__attr __fn_native_limits_get_maxint(__attr __args[]); +__attr __fn_native_limits_get_minint(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_limits(); + +#endif /* __NATIVE_LIMITS_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/list.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/list.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,147 @@ +/* Native functions for list operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* List operations. */ + +__attr __fn_native_list_list_init(__attr __args[]) +{ + __attr * const size = &__args[1]; + /* size.__data__ interpreted as int */ + unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; + __attr attr = {0, .seqvalue=__new_fragment(n)}; + + /* Return the __data__ attribute. */ + return attr; +} + +__attr __fn_native_list_list_setsize(__attr __args[]) +{ + __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, __pos___data__).intvalue; + + data->size = n; + return __builtins___none_None; +} + +__attr __fn_native_list_list_append(__attr __args[]) +{ + __attr * const self = &__args[1]; + __attr * const value = &__args[2]; + /* self.__data__ interpreted as list */ + __fragment *data = __load_via_object(self->value, __pos___data__).seqvalue; + __fragment *newdata = __fragment_append(data, value); + + /* Replace the __data__ attribute if appropriate. */ + if (newdata != data) + __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); + return __builtins___none_None; +} + +__attr __fn_native_list_list_concat(__attr __args[]) +{ + __attr * const self = &__args[1]; + __attr * const other = &__args[2]; + /* self.__data__, other interpreted as list */ + __fragment *data = __load_via_object(self->value, __pos___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; + unsigned int i, j, n; + + /* Re-allocate the fragment if the capacity has been reached. */ + if (size + other_size >= capacity) + { + n = size + other_size; + newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); + newdata->capacity = n; + } + + /* Copy the elements from the other list and increment the list size. */ + for (i = size, j = 0; j < other_size; i++, j++) + newdata->attrs[i] = other_data->attrs[j]; + newdata->size = n; + + /* Replace the __data__ attribute if appropriate. */ + if (newdata != data) + __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); + return __builtins___none_None; +} + +__attr __fn_native_list_list_len(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as fragment */ + unsigned int size = _data->seqvalue->size; + + /* Return the new integer. */ + return __new_int(size); +} + +__attr __fn_native_list_list_nonempty(__attr __args[]) +{ + __attr * const _data = &__args[1]; + + return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; +} + +__attr __fn_native_list_list_element(__attr __args[]) +{ + __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, __pos___data__).intvalue; + + return elements[i]; +} + +__attr __fn_native_list_list_setelement(__attr __args[]) +{ + __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, __pos___data__).intvalue; + + /* Set the element. */ + elements[i] = *value; + return __builtins___none_None; +} + +/* Module initialisation. */ + +void __main_native_list() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/list.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/list.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,39 @@ +/* Native functions for list operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_LIST_H__ +#define __NATIVE_LIST_H__ + +#include "types.h" + +/* 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[]); + +/* Module initialisation. */ + +void __main_native_list(); + +#endif /* __NATIVE_LIST_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/program.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/program.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,41 @@ +/* Native functions for program operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Method binding. */ + +__attr __fn_native_program_get_using(__attr __args[]) +{ + __attr * const callable = &__args[1]; + __attr * const instance = &__args[2]; + + return __replace_context(instance->value, *callable); +} + +/* Module initialisation. */ + +void __main_native_program() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/program.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/program.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,30 @@ +/* Native functions for program operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_PROGRAM_H__ +#define __NATIVE_PROGRAM_H__ + +/* Method binding. */ + +__attr __fn_native_program_get_using(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_program(); + +#endif /* __NATIVE_PROGRAM_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/str.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/str.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,134 @@ +/* Native functions for string operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* strcmp, strncpy, strlen */ +#include "native/common.h" +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* String operations. */ + +__attr __fn_native_str_str_add(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data, other interpreted as string */ + char *s = _data->strvalue; + char *o = other->strvalue; + int n = strlen(s) + strlen(o) + 1; + char *r = (char *) __ALLOCATE(n, sizeof(char)); + + strncpy(r, s, n); + strncpy(r + strlen(s), o, n - strlen(s)); /* should null terminate */ + + /* Return a new string. */ + return __new_str(r); +} + +__attr __fn_native_str_str_lt(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data, other interpreted as string */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data, other interpreted as string */ + 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 * const _data = &__args[1]; + __attr * const other = &__args[2]; + /* _data, other interpreted as string */ + 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_len(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as string */ + char *s = _data->strvalue; + + /* Return the new integer. */ + return __new_int(strlen(s)); +} + +__attr __fn_native_str_str_nonempty(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as string */ + char *s = _data->strvalue; + + return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; +} + +__attr __fn_native_str_str_ord(__attr __args[]) +{ + __attr * const _data = &__args[1]; + /* _data interpreted as string */ + char *s = _data->strvalue; + + return __new_int((unsigned int) s[0]); +} + +__attr __fn_native_str_str_substr(__attr __args[]) +{ + __attr * const _data = &__args[1]; + __attr * const start = &__args[2]; + __attr * const size = &__args[3]; + /* _data interpreted as string */ + char *s = _data->strvalue, *sub; + /* start.__data__ interpreted as int */ + int i = __load_via_object(start->value, __pos___data__).intvalue; + /* size.__data__ interpreted as int */ + int l = __load_via_object(size->value, __pos___data__).intvalue; + + /* Reserve space for a new string. */ + sub = (char *) __ALLOCATE(l + 1, sizeof(char)); + strncpy(sub, s + i, l); /* does not null terminate but final byte should be zero */ + return __new_str(sub); +} + +/* Module initialisation. */ + +void __main_native_str() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/str.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/str.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,37 @@ +/* Native functions for string operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_STR_H__ +#define __NATIVE_STR_H__ + +/* String operations. */ + +__attr __fn_native_str_str_add(__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_len(__attr __args[]); +__attr __fn_native_str_str_nonempty(__attr __args[]); +__attr __fn_native_str_str_ord(__attr __args[]); +__attr __fn_native_str_str_substr(__attr __args[]); + +/* Module initialisation. */ + +void __main_native_str(); + +#endif /* __NATIVE_STR_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/system.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/system.c Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,58 @@ +/* Native functions for system operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include /* abs, exit */ +#include "types.h" +#include "exceptions.h" +#include "ops.h" +#include "progconsts.h" +#include "progops.h" +#include "progtypes.h" +#include "main.h" + +/* Environment support. */ + +__attr __fn_native_system_exit(__attr __args[]) +{ + __attr * const status = &__args[1]; + + exit(__load_via_object(status->value, __pos___data__).intvalue); + return __builtins___none_None; +} + +__attr __fn_native_system_get_argv(__attr __args[]) +{ + __attr * const status = &__args[1]; + + /* NOTE: To be written. */ + return __builtins___none_None; +} + +__attr __fn_native_system_get_path(__attr __args[]) +{ + __attr * const status = &__args[1]; + + /* NOTE: To be written. */ + return __builtins___none_None; +} + +/* Module initialisation. */ + +void __main_native_system() +{ +} diff -r c1e29f21858e -r 4cb3b47bd18f templates/native/system.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/native/system.h Fri Dec 09 16:22:37 2016 +0100 @@ -0,0 +1,34 @@ +/* Native functions for system operations. + +Copyright (C) 2016 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 +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef __NATIVE_SYSTEM_H__ +#define __NATIVE_SYSTEM_H__ + +#include "types.h" + +/* 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[]); + +/* Module initialisation. */ + +void __main_native_system(); + +#endif /* __NATIVE_SYSTEM_H__ */ diff -r c1e29f21858e -r 4cb3b47bd18f translator.py --- a/translator.py Fri Dec 09 00:09:01 2016 +0100 +++ b/translator.py Fri Dec 09 16:22:37 2016 +0100 @@ -46,7 +46,8 @@ self.check_output() for module in self.importer.modules.values(): - if module.name != "native": + parts = module.name.split(".") + if parts[0] != "native": tm = TranslatedModule(module.name, self.importer, self.deducer, self.optimiser) tm.translate(module.filename, join(output, "%s.c" % module.name)) @@ -1479,7 +1480,7 @@ if name is not None: name_ref = self.process_structure_node(name) - self.writeline("else if (__BOOL(__fn_native__isinstance((__attr[]) {{0, 0}, __tmp_exc.arg, %s})))" % name_ref) + self.writeline("else if (__BOOL(__fn_native_introspection_isinstance((__attr[]) {{0, 0}, __tmp_exc.arg, %s})))" % name_ref) else: self.writeline("else if (1)")