1.1 --- a/templates/native.c Sun Nov 20 00:09:02 2016 +0100
1.2 +++ b/templates/native.c Sun Nov 20 00:09:36 2016 +0100
1.3 @@ -1,5 +1,8 @@
1.4 #include <stdlib.h> /* calloc, exit */
1.5 #include <unistd.h> /* read, write */
1.6 +#include <math.h> /* ceil, log10, pow */
1.7 +#include <string.h> /* strcmp, strlen */
1.8 +#include <stdio.h> /* snprintf */
1.9 #include "types.h"
1.10 #include "exceptions.h"
1.11 #include "ops.h"
1.12 @@ -8,6 +11,24 @@
1.13 #include "progtypes.h"
1.14 #include "main.h"
1.15
1.16 +/* Utility functions. */
1.17 +
1.18 +inline __attr __new_int(int i)
1.19 +{
1.20 + /* Create a new integer and mutate the __data__ attribute. */
1.21 + __attr attr = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int));
1.22 + attr.value->attrs[__pos___data__].intvalue = i;
1.23 + return attr;
1.24 +}
1.25 +
1.26 +inline __attr __new_str(char *s)
1.27 +{
1.28 + /* Create a new string and mutate the __data__ attribute. */
1.29 + __attr attr = __new(&__InstanceTable___builtins___str_string, &__builtins___str_string, sizeof(__obj___builtins___str_string));
1.30 + attr.value->attrs[__pos___data__].strvalue = s;
1.31 + return attr;
1.32 +}
1.33 +
1.34 /* Native functions. */
1.35
1.36 __attr __fn_native__exit(__attr __args[])
1.37 @@ -61,9 +82,13 @@
1.38 {
1.39 #define self (__args[1])
1.40 #define other (__args[2])
1.41 + /* self.__data__ and other.__data__ interpreted as int */
1.42 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.43 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.44
1.45 - /* NOTE: To be written. */
1.46 - return __builtins___none_None;
1.47 + /* Return the new integer. */
1.48 + /* NOTE: No overflow test applied. */
1.49 + return __new_int(i + j);
1.50 #undef self
1.51 #undef other
1.52 }
1.53 @@ -72,9 +97,13 @@
1.54 {
1.55 #define self (__args[1])
1.56 #define other (__args[2])
1.57 + /* self.__data__ and other.__data__ interpreted as int */
1.58 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.59 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.60
1.61 - /* NOTE: To be written. */
1.62 - return __builtins___none_None;
1.63 + /* Return the new integer. */
1.64 + /* NOTE: No overflow test applied. */
1.65 + return __new_int(i - j);
1.66 #undef self
1.67 #undef other
1.68 }
1.69 @@ -83,9 +112,13 @@
1.70 {
1.71 #define self (__args[1])
1.72 #define other (__args[2])
1.73 + /* self.__data__ and other.__data__ interpreted as int */
1.74 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.75 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.76
1.77 - /* NOTE: To be written. */
1.78 - return __builtins___none_None;
1.79 + /* Return the new integer. */
1.80 + /* NOTE: No overflow test applied. */
1.81 + return __new_int(i * j);
1.82 #undef self
1.83 #undef other
1.84 }
1.85 @@ -94,9 +127,13 @@
1.86 {
1.87 #define self (__args[1])
1.88 #define other (__args[2])
1.89 + /* self.__data__ and other.__data__ interpreted as int */
1.90 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.91 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.92
1.93 - /* NOTE: To be written. */
1.94 - return __builtins___none_None;
1.95 + /* Return the new integer. */
1.96 + /* NOTE: No overflow test applied. */
1.97 + return __new_int(i / j);
1.98 #undef self
1.99 #undef other
1.100 }
1.101 @@ -105,9 +142,13 @@
1.102 {
1.103 #define self (__args[1])
1.104 #define other (__args[2])
1.105 + /* self.__data__ and other.__data__ interpreted as int */
1.106 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.107 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.108
1.109 - /* NOTE: To be written. */
1.110 - return __builtins___none_None;
1.111 + /* Return the new integer. */
1.112 + /* NOTE: No overflow test applied. */
1.113 + return __new_int(i % j);
1.114 #undef self
1.115 #undef other
1.116 }
1.117 @@ -116,9 +157,13 @@
1.118 {
1.119 #define self (__args[1])
1.120 #define other (__args[2])
1.121 + /* self.__data__ and other.__data__ interpreted as int */
1.122 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.123 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.124
1.125 - /* NOTE: To be written. */
1.126 - return __builtins___none_None;
1.127 + /* Return the new integer. */
1.128 + /* NOTE: No overflow test applied. */
1.129 + return __new_int((int) pow(i, j));
1.130 #undef self
1.131 #undef other
1.132 }
1.133 @@ -127,9 +172,13 @@
1.134 {
1.135 #define self (__args[1])
1.136 #define other (__args[2])
1.137 + /* self.__data__ and other.__data__ interpreted as int */
1.138 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.139 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.140
1.141 - /* NOTE: To be written. */
1.142 - return __builtins___none_None;
1.143 + /* Return the new integer. */
1.144 + /* NOTE: No overflow test applied. */
1.145 + return __new_int(i & j);
1.146 #undef self
1.147 #undef other
1.148 }
1.149 @@ -138,9 +187,13 @@
1.150 {
1.151 #define self (__args[1])
1.152 #define other (__args[2])
1.153 + /* self.__data__ and other.__data__ interpreted as int */
1.154 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.155 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.156
1.157 - /* NOTE: To be written. */
1.158 - return __builtins___none_None;
1.159 + /* Return the new integer. */
1.160 + /* NOTE: No overflow test applied. */
1.161 + return __new_int(i | j);
1.162 #undef self
1.163 #undef other
1.164 }
1.165 @@ -149,53 +202,13 @@
1.166 {
1.167 #define self (__args[1])
1.168 #define other (__args[2])
1.169 -
1.170 - /* NOTE: To be written. */
1.171 - return __builtins___none_None;
1.172 - #undef self
1.173 - #undef other
1.174 -}
1.175 -
1.176 -__attr __fn_native__int_rsub(__attr __args[])
1.177 -{
1.178 - #define self (__args[1])
1.179 - #define other (__args[2])
1.180 -
1.181 - /* NOTE: To be written. */
1.182 - return __builtins___none_None;
1.183 - #undef self
1.184 - #undef other
1.185 -}
1.186 -
1.187 -__attr __fn_native__int_rdiv(__attr __args[])
1.188 -{
1.189 - #define self (__args[1])
1.190 - #define other (__args[2])
1.191 + /* self.__data__ and other.__data__ interpreted as int */
1.192 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.193 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.194
1.195 - /* NOTE: To be written. */
1.196 - return __builtins___none_None;
1.197 - #undef self
1.198 - #undef other
1.199 -}
1.200 -
1.201 -__attr __fn_native__int_rmod(__attr __args[])
1.202 -{
1.203 - #define self (__args[1])
1.204 - #define other (__args[2])
1.205 -
1.206 - /* NOTE: To be written. */
1.207 - return __builtins___none_None;
1.208 - #undef self
1.209 - #undef other
1.210 -}
1.211 -
1.212 -__attr __fn_native__int_rpow(__attr __args[])
1.213 -{
1.214 - #define self (__args[1])
1.215 - #define other (__args[2])
1.216 -
1.217 - /* NOTE: To be written. */
1.218 - return __builtins___none_None;
1.219 + /* Return the new integer. */
1.220 + /* NOTE: No overflow test applied. */
1.221 + return __new_int(i ^ j);
1.222 #undef self
1.223 #undef other
1.224 }
1.225 @@ -204,9 +217,12 @@
1.226 {
1.227 #define self (__args[1])
1.228 #define other (__args[2])
1.229 + /* self.__data__ and other.__data__ interpreted as int */
1.230 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.231 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.232
1.233 - /* NOTE: To be written. */
1.234 - return __builtins___none_None;
1.235 + /* Return a boolean result. */
1.236 + return i < j ? __builtins___boolean_True : __builtins___boolean_False;
1.237 #undef self
1.238 #undef other
1.239 }
1.240 @@ -215,9 +231,12 @@
1.241 {
1.242 #define self (__args[1])
1.243 #define other (__args[2])
1.244 + /* self.__data__ and other.__data__ interpreted as int */
1.245 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.246 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.247
1.248 - /* NOTE: To be written. */
1.249 - return __builtins___none_None;
1.250 + /* Return a boolean result. */
1.251 + return i > j ? __builtins___boolean_True : __builtins___boolean_False;
1.252 #undef self
1.253 #undef other
1.254 }
1.255 @@ -226,9 +245,43 @@
1.256 {
1.257 #define self (__args[1])
1.258 #define other (__args[2])
1.259 + /* self.__data__ and other.__data__ interpreted as int */
1.260 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.261 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.262
1.263 - /* NOTE: To be written. */
1.264 - return __builtins___none_None;
1.265 + /* Return a boolean result. */
1.266 + return i == j ? __builtins___boolean_True : __builtins___boolean_False;
1.267 + #undef self
1.268 + #undef other
1.269 +}
1.270 +
1.271 +__attr __fn_native__int_ne(__attr __args[])
1.272 +{
1.273 + #define self (__args[1])
1.274 + #define other (__args[2])
1.275 + /* self.__data__ and other.__data__ interpreted as int */
1.276 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.277 + int j = __load_via_object(other.value, __pos___data__).intvalue;
1.278 +
1.279 + /* Return a boolean result. */
1.280 + return i != j ? __builtins___boolean_True : __builtins___boolean_False;
1.281 + #undef self
1.282 + #undef other
1.283 +}
1.284 +
1.285 +__attr __fn_native__int_str(__attr __args[])
1.286 +{
1.287 + #define self (__args[1])
1.288 + /* self.__data__ interpreted as int */
1.289 + int i = __load_via_object(self.value, __pos___data__).intvalue;
1.290 + int n = i != 0 ? (int) ceil(log10(i+1)) + 1 : 2;
1.291 + char *s = calloc(n, sizeof(char));
1.292 +
1.293 + if (i < 0) n++;
1.294 + snprintf(s, n, "%d", i);
1.295 +
1.296 + /* Return a new string. */
1.297 + return __new_str(s);
1.298 #undef self
1.299 #undef other
1.300 }
1.301 @@ -237,9 +290,17 @@
1.302 {
1.303 #define self (__args[1])
1.304 #define other (__args[2])
1.305 + /* self.__data__, other.__data__ interpreted as string */
1.306 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.307 + char *o = __load_via_object(other.value, __pos___data__).strvalue;
1.308 + int n = strlen(s) + strlen(o) + 1;
1.309 + char *r = calloc(n, sizeof(char));
1.310
1.311 - /* NOTE: To be written. */
1.312 - return __builtins___none_None;
1.313 + strncpy(r, s, n);
1.314 + strncpy(r + strlen(s), o, n - strlen(s));
1.315 +
1.316 + /* Return a new string. */
1.317 + return __new_str(r);
1.318 #undef self
1.319 #undef other
1.320 }
1.321 @@ -248,9 +309,12 @@
1.322 {
1.323 #define self (__args[1])
1.324 #define other (__args[2])
1.325 + /* self.__data__, other.__data__ interpreted as string */
1.326 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.327 + char *o = __load_via_object(other.value, __pos___data__).strvalue;
1.328
1.329 - /* NOTE: To be written. */
1.330 - return __builtins___none_None;
1.331 + /* NOTE: Using simple byte-level string operations. */
1.332 + return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False;
1.333 #undef self
1.334 #undef other
1.335 }
1.336 @@ -259,9 +323,12 @@
1.337 {
1.338 #define self (__args[1])
1.339 #define other (__args[2])
1.340 + /* self.__data__, other.__data__ interpreted as string */
1.341 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.342 + char *o = __load_via_object(other.value, __pos___data__).strvalue;
1.343
1.344 - /* NOTE: To be written. */
1.345 - return __builtins___none_None;
1.346 + /* NOTE: Using simple byte-level string operations. */
1.347 + return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False;
1.348 #undef self
1.349 #undef other
1.350 }
1.351 @@ -270,9 +337,12 @@
1.352 {
1.353 #define self (__args[1])
1.354 #define other (__args[2])
1.355 + /* self.__data__, other.__data__ interpreted as string */
1.356 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.357 + char *o = __load_via_object(other.value, __pos___data__).strvalue;
1.358
1.359 - /* NOTE: To be written. */
1.360 - return __builtins___none_None;
1.361 + /* NOTE: Using simple byte-level string operations. */
1.362 + return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False;
1.363 #undef self
1.364 #undef other
1.365 }
1.366 @@ -280,25 +350,28 @@
1.367 __attr __fn_native__str_len(__attr __args[])
1.368 {
1.369 #define self (__args[1])
1.370 + /* self.__data__ interpreted as string */
1.371 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.372
1.373 - /* NOTE: To be written. */
1.374 - return __builtins___none_None;
1.375 + /* Return the new integer. */
1.376 + return __new_int(strlen(s));
1.377 #undef self
1.378 }
1.379
1.380 __attr __fn_native__str_nonempty(__attr __args[])
1.381 {
1.382 #define self (__args[1])
1.383 + /* self.__data__ interpreted as string */
1.384 + char *s = __load_via_object(self.value, __pos___data__).strvalue;
1.385
1.386 - /* NOTE: To be written. */
1.387 - return __builtins___none_None;
1.388 + return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False;
1.389 #undef self
1.390 }
1.391
1.392 __attr __fn_native__list_init(__attr __args[])
1.393 {
1.394 #define size (__args[1])
1.395 - /* size.__data__ interpreted as int */
1.396 + /* size.__data__ interpreted as fragment */
1.397 __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr));
1.398 __attr attr = {0, .data=data};
1.399
1.400 @@ -312,12 +385,8 @@
1.401 /* self.__data__ interpreted as fragment */
1.402 unsigned int size = __load_via_object(self.value, __pos___data__).data->size;
1.403
1.404 - /* Create a new integer and mutate the __data__ attribute. */
1.405 - __attr length = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int));
1.406 - length.value->attrs[__pos___data__].intvalue = size;
1.407 -
1.408 /* Return the new integer. */
1.409 - return length;
1.410 + return __new_int(size);
1.411 #undef self
1.412 }
1.413
1.414 @@ -333,9 +402,12 @@
1.415 {
1.416 #define self (__args[1])
1.417 #define index (__args[2])
1.418 + /* self.__data__ interpreted as fragment */
1.419 + __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs;
1.420 + /* index.__data__ interpreted as int */
1.421 + int i = __load_via_object(index.value, __pos___data__).intvalue;
1.422
1.423 - /* NOTE: To be written. */
1.424 - return __builtins___none_None;
1.425 + return elements[i];
1.426 #undef self
1.427 #undef index
1.428 }
1.429 @@ -352,7 +424,7 @@
1.430 __attr __fn_native__tuple_init(__attr __args[])
1.431 {
1.432 #define size (__args[1])
1.433 - /* size.__data__ interpreted as int */
1.434 + /* size.__data__ interpreted as fragment */
1.435 __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr));
1.436 __attr attr = {0, .data=data};
1.437
1.438 @@ -363,9 +435,11 @@
1.439 __attr __fn_native__tuple_len(__attr __args[])
1.440 {
1.441 #define self (__args[1])
1.442 + /* self.__data__ interpreted as fragment */
1.443 + unsigned int size = __load_via_object(self.value, __pos___data__).data->size;
1.444
1.445 - /* NOTE: To be written. */
1.446 - return __builtins___none_None;
1.447 + /* Return the new integer. */
1.448 + return __new_int(size);
1.449 #undef self
1.450 }
1.451
1.452 @@ -373,9 +447,12 @@
1.453 {
1.454 #define self (__args[1])
1.455 #define index (__args[2])
1.456 + /* self.__data__ interpreted as fragment */
1.457 + __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs;
1.458 + /* index.__data__ interpreted as int */
1.459 + int i = __load_via_object(index.value, __pos___data__).intvalue;
1.460
1.461 - /* NOTE: To be written. */
1.462 - return __builtins___none_None;
1.463 + return elements[i];
1.464 #undef self
1.465 #undef index
1.466 }
1.467 @@ -386,9 +463,9 @@
1.468 #define cls (__args[2])
1.469
1.470 if (__is_instance(obj.value) && __HASATTR(__get_class(obj.value), __TYPEPOS(cls.value), __TYPECODE(cls.value)))
1.471 - return obj;
1.472 + return __builtins___boolean_True;
1.473 else
1.474 - return __builtins___none_None;
1.475 + return __builtins___boolean_False;
1.476 #undef obj
1.477 #undef cls
1.478 }
1.479 @@ -408,8 +485,12 @@
1.480 {
1.481 #define fd (__args[1])
1.482 #define str (__args[2])
1.483 + /* fd.__data__ interpreted as int */
1.484 + int i = __load_via_object(fd.value, __pos___data__).intvalue;
1.485 + /* str.__data__ interpreted as string */
1.486 + char *s = __load_via_object(str.value, __pos___data__).strvalue;
1.487
1.488 - /* NOTE: To be written. */
1.489 + write(i, s, sizeof(char) * strlen(s));
1.490 return __builtins___none_None;
1.491 #undef fd
1.492 #undef str