# HG changeset patch # User Paul Boddie # Date 1479596976 -3600 # Node ID e0a514cecae1fb510e2e0092f23cd5900685666d # Parent 21a9fbe41d8beca8de6395ad6bc3f5e65caa1b6b Added tentative implementations of several native functions. diff -r 21a9fbe41d8b -r e0a514cecae1 lib/__builtins__/int.py --- a/lib/__builtins__/int.py Sun Nov 20 00:09:02 2016 +0100 +++ b/lib/__builtins__/int.py Sun Nov 20 00:09:36 2016 +0100 @@ -77,14 +77,14 @@ def __rsub__(self, other): "Return a new int for the operation." - return _binary_op(self, other, native._int_rsub) + return _binary_op(other, self, native._int_sub) __mul__ = __rmul__ = __imul__ __div__ = __idiv__ def __rdiv__(self, other): "Return a new int for the operation." - return _binary_op(self, other, native._int_rdiv) + return _binary_op(other, self, native._int_div) def __floordiv__(self, other): pass def __rfloordiv__(self, other): pass @@ -94,13 +94,13 @@ def __rmod__(self, other): "Return a new int for the operation." - return _binary_op(self, other, native._int_rmod) + return _binary_op(other, self, native._int_mod) __pow__ = __ipow__ def __rpow__(self, other): "Return a new int for the operation." - return _binary_op(self, other, native._int_rpow) + return _binary_op(other, self, native._int_pow) __and__ = __rand__ = __iand__ __or__ = __ror__ = __ior__ @@ -133,7 +133,11 @@ def __invert__(self): pass def __neg__(self): pass def __pos__(self): pass - def __str__(self): pass + + def __str__(self): + "Return a string representation." + return native._int_str(self) + def __lshift__(self): pass def __rlshift__(self): pass def __rshift__(self): pass @@ -143,6 +147,6 @@ def __bool__(self): "Return whether this int is non-zero." - return _negate(native._int_eq(self, 0)) + return native._int_ne(self, 0) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 21a9fbe41d8b -r e0a514cecae1 lib/__builtins__/list.py --- a/lib/__builtins__/list.py Sun Nov 20 00:09:02 2016 +0100 +++ b/lib/__builtins__/list.py Sun Nov 20 00:09:36 2016 +0100 @@ -78,7 +78,14 @@ def __add__(self, other): pass def __iadd__(self, other): pass - def __str__(self): pass + + def __str__(self): + + "Return a string representation of the list." + + # NOTE: To be implemented, maybe using a buffer. + + return "[...]" def __bool__(self): diff -r 21a9fbe41d8b -r e0a514cecae1 lib/native.py --- a/lib/native.py Sun Nov 20 00:09:02 2016 +0100 +++ b/lib/native.py Sun Nov 20 00:09:36 2016 +0100 @@ -33,11 +33,6 @@ def _int_pow(self, other): pass def _int_sub(self, other): pass -def _int_rdiv(self, other): pass -def _int_rmod(self, other): pass -def _int_rpow(self, other): pass -def _int_rsub(self, other): pass - def _int_and(self, other): pass def _int_or(self, other): pass def _int_xor(self, other): pass @@ -45,6 +40,9 @@ 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 def _str_add(self, other): pass def _str_lt(self, other): pass diff -r 21a9fbe41d8b -r e0a514cecae1 templates/Makefile --- a/templates/Makefile Sun Nov 20 00:09:02 2016 +0100 +++ b/templates/Makefile Sun Nov 20 00:09:36 2016 +0100 @@ -1,6 +1,7 @@ SRC = exceptions.c main.c native.c ops.c progops.c progtypes.c $(wildcard src/*.c) OBJ = $(SRC:.c=.o) CFLAGS = -I. +LDFLAGS = -lm all: main diff -r 21a9fbe41d8b -r e0a514cecae1 templates/Makefile-debug --- a/templates/Makefile-debug Sun Nov 20 00:09:02 2016 +0100 +++ b/templates/Makefile-debug Sun Nov 20 00:09:36 2016 +0100 @@ -1,6 +1,7 @@ SRC = exceptions.c main.c native.c ops.c progops.c progtypes.c $(wildcard src/*.c) OBJ = $(SRC:.c=.o) CFLAGS = -I. -g +LDFLAGS = -lm all: main diff -r 21a9fbe41d8b -r e0a514cecae1 templates/native.c --- a/templates/native.c Sun Nov 20 00:09:02 2016 +0100 +++ b/templates/native.c Sun Nov 20 00:09:36 2016 +0100 @@ -1,5 +1,8 @@ #include /* calloc, exit */ #include /* read, write */ +#include /* ceil, log10, pow */ +#include /* strcmp, strlen */ +#include /* snprintf */ #include "types.h" #include "exceptions.h" #include "ops.h" @@ -8,6 +11,24 @@ #include "progtypes.h" #include "main.h" +/* Utility functions. */ + +inline __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; +} + +inline __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; +} + /* Native functions. */ __attr __fn_native__exit(__attr __args[]) @@ -61,9 +82,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i + j); #undef self #undef other } @@ -72,9 +97,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i - j); #undef self #undef other } @@ -83,9 +112,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i * j); #undef self #undef other } @@ -94,9 +127,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i / j); #undef self #undef other } @@ -105,9 +142,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i % j); #undef self #undef other } @@ -116,9 +157,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int((int) pow(i, j)); #undef self #undef other } @@ -127,9 +172,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i & j); #undef self #undef other } @@ -138,9 +187,13 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i | j); #undef self #undef other } @@ -149,53 +202,13 @@ { #define self (__args[1]) #define other (__args[2]) - - /* NOTE: To be written. */ - return __builtins___none_None; - #undef self - #undef other -} - -__attr __fn_native__int_rsub(__attr __args[]) -{ - #define self (__args[1]) - #define other (__args[2]) - - /* NOTE: To be written. */ - return __builtins___none_None; - #undef self - #undef other -} - -__attr __fn_native__int_rdiv(__attr __args[]) -{ - #define self (__args[1]) - #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; - #undef self - #undef other -} - -__attr __fn_native__int_rmod(__attr __args[]) -{ - #define self (__args[1]) - #define other (__args[2]) - - /* NOTE: To be written. */ - return __builtins___none_None; - #undef self - #undef other -} - -__attr __fn_native__int_rpow(__attr __args[]) -{ - #define self (__args[1]) - #define other (__args[2]) - - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i ^ j); #undef self #undef other } @@ -204,9 +217,12 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return a boolean result. */ + return i < j ? __builtins___boolean_True : __builtins___boolean_False; #undef self #undef other } @@ -215,9 +231,12 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return a boolean result. */ + return i > j ? __builtins___boolean_True : __builtins___boolean_False; #undef self #undef other } @@ -226,9 +245,43 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return a boolean result. */ + return i == j ? __builtins___boolean_True : __builtins___boolean_False; + #undef self + #undef other +} + +__attr __fn_native__int_ne(__attr __args[]) +{ + #define self (__args[1]) + #define other (__args[2]) + /* self.__data__ and other.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int j = __load_via_object(other.value, __pos___data__).intvalue; + + /* Return a boolean result. */ + return i != j ? __builtins___boolean_True : __builtins___boolean_False; + #undef self + #undef other +} + +__attr __fn_native__int_str(__attr __args[]) +{ + #define self (__args[1]) + /* self.__data__ interpreted as int */ + int i = __load_via_object(self.value, __pos___data__).intvalue; + int n = i != 0 ? (int) ceil(log10(i+1)) + 1 : 2; + char *s = calloc(n, sizeof(char)); + + if (i < 0) n++; + snprintf(s, n, "%d", i); + + /* Return a new string. */ + return __new_str(s); #undef self #undef other } @@ -237,9 +290,17 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__, other.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; + char *o = __load_via_object(other.value, __pos___data__).strvalue; + int n = strlen(s) + strlen(o) + 1; + char *r = calloc(n, sizeof(char)); - /* NOTE: To be written. */ - return __builtins___none_None; + strncpy(r, s, n); + strncpy(r + strlen(s), o, n - strlen(s)); + + /* Return a new string. */ + return __new_str(r); #undef self #undef other } @@ -248,9 +309,12 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__, other.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; + char *o = __load_via_object(other.value, __pos___data__).strvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* NOTE: Using simple byte-level string operations. */ + return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; #undef self #undef other } @@ -259,9 +323,12 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__, other.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; + char *o = __load_via_object(other.value, __pos___data__).strvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* NOTE: Using simple byte-level string operations. */ + return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; #undef self #undef other } @@ -270,9 +337,12 @@ { #define self (__args[1]) #define other (__args[2]) + /* self.__data__, other.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; + char *o = __load_via_object(other.value, __pos___data__).strvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* NOTE: Using simple byte-level string operations. */ + return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; #undef self #undef other } @@ -280,25 +350,28 @@ __attr __fn_native__str_len(__attr __args[]) { #define self (__args[1]) + /* self.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + return __new_int(strlen(s)); #undef self } __attr __fn_native__str_nonempty(__attr __args[]) { #define self (__args[1]) + /* self.__data__ interpreted as string */ + char *s = __load_via_object(self.value, __pos___data__).strvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; #undef self } __attr __fn_native__list_init(__attr __args[]) { #define size (__args[1]) - /* size.__data__ interpreted as int */ + /* size.__data__ interpreted as fragment */ __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr)); __attr attr = {0, .data=data}; @@ -312,12 +385,8 @@ /* self.__data__ interpreted as fragment */ unsigned int size = __load_via_object(self.value, __pos___data__).data->size; - /* Create a new integer and mutate the __data__ attribute. */ - __attr length = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int)); - length.value->attrs[__pos___data__].intvalue = size; - /* Return the new integer. */ - return length; + return __new_int(size); #undef self } @@ -333,9 +402,12 @@ { #define self (__args[1]) #define index (__args[2]) + /* self.__data__ interpreted as fragment */ + __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs; + /* index.__data__ interpreted as int */ + int i = __load_via_object(index.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + return elements[i]; #undef self #undef index } @@ -352,7 +424,7 @@ __attr __fn_native__tuple_init(__attr __args[]) { #define size (__args[1]) - /* size.__data__ interpreted as int */ + /* size.__data__ interpreted as fragment */ __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr)); __attr attr = {0, .data=data}; @@ -363,9 +435,11 @@ __attr __fn_native__tuple_len(__attr __args[]) { #define self (__args[1]) + /* self.__data__ interpreted as fragment */ + unsigned int size = __load_via_object(self.value, __pos___data__).data->size; - /* NOTE: To be written. */ - return __builtins___none_None; + /* Return the new integer. */ + return __new_int(size); #undef self } @@ -373,9 +447,12 @@ { #define self (__args[1]) #define index (__args[2]) + /* self.__data__ interpreted as fragment */ + __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs; + /* index.__data__ interpreted as int */ + int i = __load_via_object(index.value, __pos___data__).intvalue; - /* NOTE: To be written. */ - return __builtins___none_None; + return elements[i]; #undef self #undef index } @@ -386,9 +463,9 @@ #define cls (__args[2]) if (__is_instance(obj.value) && __HASATTR(__get_class(obj.value), __TYPEPOS(cls.value), __TYPECODE(cls.value))) - return obj; + return __builtins___boolean_True; else - return __builtins___none_None; + return __builtins___boolean_False; #undef obj #undef cls } @@ -408,8 +485,12 @@ { #define fd (__args[1]) #define 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; - /* NOTE: To be written. */ + write(i, s, sizeof(char) * strlen(s)); return __builtins___none_None; #undef fd #undef str diff -r 21a9fbe41d8b -r e0a514cecae1 templates/native.h --- a/templates/native.h Sun Nov 20 00:09:02 2016 +0100 +++ b/templates/native.h Sun Nov 20 00:09:36 2016 +0100 @@ -29,6 +29,9 @@ __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[]); __attr __fn_native__str_add(__attr __args[]); __attr __fn_native__str_lt(__attr __args[]);