mirror of
https://github.com/anoma/juvix.git
synced 2025-01-07 08:08:44 +03:00
6eb16c74c1
* match inductive definitions * progress towards builtins * more progress towards builtin types * add more builtins * add some errors * add reverse table to builtins * Squashed commit of the following: commit 93333de502d8dd546eb8edf697ca7eef972ea105 Author: Paul Cadman <git@paulcadman.dev> Date: Mon Jun 27 18:21:30 2022 +0100 Use builtin names for match and project functions Add an implementation of nat for the standalone backend commit 868d2098ee57b7acbca84512b6e096650eeeb22d Author: Jan Mas Rovira <janmasrovira@gmail.com> Date: Mon Jun 27 18:15:29 2022 +0200 add builtin information to ClosureInfo commit 32c78aceb19ee4010d66090a3c4e6025621b5c1f Author: Paul Cadman <git@paulcadman.dev> Date: Mon Jun 27 12:52:10 2022 +0100 Refactor BuiltinEnum to sum type of each Builtin commit 55bb72ab12a8fb7d10070c2dee5875482453b7c6 Author: Paul Cadman <git@paulcadman.dev> Date: Fri Jun 24 14:44:28 2022 +0100 Add Builtin information to Mono InfoTable commit a72368f2e3af20baaf44c5e21fa7e6a469cf1ac5 Author: Paul Cadman <git@paulcadman.dev> Date: Fri Jun 24 14:41:51 2022 +0100 Add Bitraversable to Prelude commit afa3153d82a9509b0882e7ca99830040fad9ef65 Author: Paul Cadman <git@paulcadman.dev> Date: Fri Jun 24 14:41:39 2022 +0100 Remove unused import commit ea0b7848fb80970e03a0561be3fb4448486a89a9 Author: Paul Cadman <git@paulcadman.dev> Date: Thu Jun 23 13:54:58 2022 +0100 Use projection functions instead of direct member access * Avoid shadowing C runtime names in foreign block * Fix formatting * Update C names for builtin functions * Add prim_ prefix to builtin C names Implement builtins for standalone and libc backends * Update ormolu action * ci: run all tests for draft PRs Co-authored-by: Paul Cadman <git@paulcadman.dev>
263 lines
5.2 KiB
C
263 lines
5.2 KiB
C
#ifndef MINIC_RUNTIME_H_
|
|
#define MINIC_RUNTIME_H_
|
|
|
|
#include "nat.h"
|
|
#include "io.h"
|
|
|
|
typedef __SIZE_TYPE__ size_t;
|
|
typedef __UINT8_TYPE__ uint8_t;
|
|
typedef __UINT16_TYPE__ uint16_t;
|
|
typedef __UINT32_TYPE__ uint32_t;
|
|
typedef __UINTPTR_TYPE__ uintptr_t;
|
|
|
|
typedef struct minijuvix_function {
|
|
uintptr_t fun;
|
|
} minijuvix_function_t;
|
|
|
|
/**
|
|
* Allocator
|
|
*/
|
|
|
|
void *malloc(size_t size);
|
|
void free(void *p);
|
|
|
|
void* memcpy(void *dest, const void *src, size_t n) {
|
|
char *csrc = (char*) src;
|
|
char *cdest = (char*) dest;
|
|
|
|
for (int i=0; i < n; i++) {
|
|
cdest[i] = csrc[i];
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
void* realloc(void *ptr, size_t n) {
|
|
void* newptr;
|
|
newptr = malloc(n);
|
|
memcpy(newptr, ptr, n);
|
|
free(ptr);
|
|
return newptr;
|
|
}
|
|
|
|
/**
|
|
* WASI Definitions
|
|
*/
|
|
|
|
typedef struct Ciovec {
|
|
uint8_t *buf;
|
|
uint32_t buf_len;
|
|
} Ciovec_t;
|
|
|
|
uint16_t fd_write(uint32_t fd, Ciovec_t *iovs_ptr, uint32_t iovs_len, uint32_t *nwritten)
|
|
__attribute__((
|
|
__import_module__("wasi_snapshot_preview1"),
|
|
__import_name__("fd_write"),
|
|
));
|
|
|
|
uint16_t fd_read(uint32_t fd, Ciovec_t *iovs_ptr, uint32_t iovs_len, uint32_t *read)
|
|
__attribute__((
|
|
__import_module__("wasi_snapshot_preview1"),
|
|
__import_name__("fd_read"),
|
|
));
|
|
|
|
_Noreturn void proc_exit(uint32_t rval)
|
|
__attribute__((
|
|
__import_module__("wasi_snapshot_preview1"),
|
|
__import_name__("proc_exit"),
|
|
));
|
|
|
|
/**
|
|
* stdlib.h
|
|
*/
|
|
|
|
#define EXIT_FAILURE 1
|
|
|
|
_Noreturn void exit(int rval) {
|
|
proc_exit(rval);
|
|
}
|
|
|
|
/**
|
|
* string.h
|
|
*/
|
|
|
|
int strcmp(const char *s1, const char *s2) {
|
|
while (*s1) {
|
|
if (*s1 != *s2) {
|
|
break;
|
|
}
|
|
s1++;
|
|
s2++;
|
|
}
|
|
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
|
}
|
|
|
|
size_t strlen(const char *s) {
|
|
const char* p = s;
|
|
while(*p!='\0') {
|
|
++p;
|
|
}
|
|
return p - s;
|
|
}
|
|
|
|
/**
|
|
* Utilities
|
|
*/
|
|
|
|
/**
|
|
* C++ version 0.4 char* style "itoa":
|
|
* Written by Lukás Chmela
|
|
* Released under GPLv3.
|
|
|
|
*/
|
|
char* itoa(int value, char* result, int base) {
|
|
// check that the base if valid
|
|
if (base < 2 || base > 36) { *result = '\0'; return result; }
|
|
|
|
char* ptr = result, *ptr1 = result, tmp_char;
|
|
int tmp_value;
|
|
|
|
do {
|
|
tmp_value = value;
|
|
value /= base;
|
|
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
|
|
} while ( value );
|
|
|
|
// Apply negative sign
|
|
if (tmp_value < 0) *ptr++ = '-';
|
|
*ptr-- = '\0';
|
|
while(ptr1 < ptr) {
|
|
tmp_char = *ptr;
|
|
*ptr--= *ptr1;
|
|
*ptr1++ = tmp_char;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
char* intToStr(int i) {
|
|
// int will occupy at least one char
|
|
size_t len = 1;
|
|
|
|
// calculate the size of the digits
|
|
int n = i < 0 ? -i : i;
|
|
while (n >= 10) {
|
|
n /= 10;
|
|
len += 1;
|
|
}
|
|
|
|
// add an extra char for the negative sign
|
|
if (i < 0) {
|
|
len += 1;
|
|
}
|
|
|
|
char* buf = (char*)malloc(len + 1);
|
|
itoa(i, buf, 10);
|
|
return buf;
|
|
}
|
|
|
|
int strToInt(char *str)
|
|
{
|
|
int result;
|
|
int puiss;
|
|
|
|
result = 0;
|
|
puiss = 1;
|
|
while (('-' == (*str)) || ((*str) == '+'))
|
|
{
|
|
if (*str == '-')
|
|
puiss = puiss * -1;
|
|
str++;
|
|
}
|
|
while ((*str >= '0') && (*str <= '9'))
|
|
{
|
|
result = (result * 10) + ((*str) - '0');
|
|
str++;
|
|
}
|
|
return (result * puiss);
|
|
}
|
|
|
|
int putStr(const char* str) {
|
|
size_t n = strlen(str);
|
|
Ciovec_t vec = {.buf = (uint8_t*)str, .buf_len=(uint32_t)n};
|
|
return fd_write(1, &vec, 1, 0);
|
|
}
|
|
|
|
int putStrLn(const char* str) {
|
|
return putStr(str) || putStr("\n");
|
|
}
|
|
|
|
prim_io prim_printNat(prim_nat n) {
|
|
return putStrLn(intToStr(n));
|
|
}
|
|
|
|
// Tries to parse str as a positive integer.
|
|
// Returns -1 if parsing fails.
|
|
int parsePositiveInt(char *str) {
|
|
int result = 0;
|
|
char* p = str;
|
|
size_t len = strlen(str);
|
|
while ((*str >= '0') && (*str <= '9'))
|
|
{
|
|
result = (result * 10) + ((*str) - '0');
|
|
str++;
|
|
}
|
|
if (str - p != len) return -1;
|
|
return result;
|
|
}
|
|
|
|
|
|
char* concat(const char* s1, const char* s2) {
|
|
const size_t len1 = strlen(s1);
|
|
const size_t len2 = strlen(s2);
|
|
int i,j=0,count=0;
|
|
char* result = (char*)malloc(len1 + len2 + 1);
|
|
|
|
for(i=0; i < len1; i++) {
|
|
result[i] = s1[i];
|
|
count++;
|
|
}
|
|
|
|
for(i=count; j < len2; i++) {
|
|
result[i] = s2[j];
|
|
j++;
|
|
}
|
|
|
|
result[len1 + len2] = '\0';
|
|
return result;
|
|
}
|
|
|
|
int getchar() {
|
|
int ch;
|
|
Ciovec_t v = {.buf = (uint8_t*) &ch, .buf_len=1};
|
|
if (fd_read(0, &v, 1, 0) != 0) return -1;
|
|
return ch;
|
|
}
|
|
|
|
char* readline() {
|
|
int i = 0, bytesAlloced = 64;
|
|
char* buffer = (char*) malloc(bytesAlloced);
|
|
int bufferSize = bytesAlloced;
|
|
|
|
for (;;++i) {
|
|
int ch;
|
|
|
|
if (i == bufferSize - 1) {
|
|
bytesAlloced += bytesAlloced;
|
|
buffer = (char*) realloc(buffer, bytesAlloced);
|
|
bufferSize = bytesAlloced;
|
|
}
|
|
|
|
ch = getchar();
|
|
if (ch == -1) {
|
|
free(buffer);
|
|
return 0;
|
|
}
|
|
if (ch == '\n') break;
|
|
buffer[i] = ch;
|
|
}
|
|
|
|
buffer[i] = '\0';
|
|
return buffer;
|
|
}
|
|
|
|
#endif // MINIC_RUNTIME_H_
|