Cleanup of builtins
This commit is contained in:
parent
7355b2f7fe
commit
d46925dbfa
6
Makefile
6
Makefile
@ -24,14 +24,14 @@ G=-ggdb
|
||||
O=-Og
|
||||
CFLAGS=$(CCONFIG) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS)
|
||||
LDLIBS=-lgc -lgccjit -lcord -lm -lunistring
|
||||
BUILTIN_OBJS=builtins/array.o builtins/bool.o builtins/builtins.o builtins/floats.o builtins/functions.o builtins/integers.o \
|
||||
BUILTIN_OBJS=builtins/array.o builtins/bool.o builtins/floats.o builtins/functions.o builtins/integers.o \
|
||||
builtins/pointer.o builtins/memory.o builtins/string.o builtins/table.o builtins/types.o
|
||||
|
||||
all: nextlang libnext.so
|
||||
all: libnext.so nextlang
|
||||
|
||||
nextlang: nextlang.c SipHash/halfsiphash.o util.o files.o ast.o parse.o environment.o types.o typecheck.o compile.o $(BUILTIN_OBJS)
|
||||
|
||||
libnext.so: util.o SipHash/halfsiphash.o
|
||||
libnext.so: util.o $(BUILTIN_OBJS) SipHash/halfsiphash.o
|
||||
$(CC) $^ $(CFLAGS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LDLIBS) -Wl,-soname,libnext.so -shared -o $@
|
||||
|
||||
SipHash/halfsiphash.c:
|
||||
|
4
ast.c
4
ast.c
@ -85,8 +85,8 @@ CORD ast_to_cord(ast_t *ast)
|
||||
T(Nil, "(%r)", type_ast_to_cord(data.type))
|
||||
T(Bool, "(\x1b[35m%s\x1b[m)", data.b ? "yes" : "no")
|
||||
T(Var, "(\x1b[36;1m%s\x1b[m)", data.name)
|
||||
T(Int, "(\x1b[35m%ld\x1b[m, precision=\x1b[35m%ld\x1b[m)", data.i, data.precision)
|
||||
T(Num, "(\x1b[35m%ld\x1b[m, precision=\x1b[35m%ld\x1b[m)", data.n, data.precision)
|
||||
T(Int, "(\x1b[35m%ld\x1b[m, bits=\x1b[35m%ld\x1b[m)", data.i, data.bits)
|
||||
T(Num, "(\x1b[35m%ld\x1b[m, bits=\x1b[35m%ld\x1b[m)", data.n, data.bits)
|
||||
T(StringLiteral, "\x1b[35m\"%r\"\x1b[m", data.cord)
|
||||
T(StringJoin, "(%r)", ast_list_to_cord(data.children))
|
||||
T(Declare, "(var=%s, value=%r)", ast_to_cord(data.var), ast_to_cord(data.value))
|
||||
|
4
ast.h
4
ast.h
@ -124,11 +124,11 @@ struct ast_s {
|
||||
} Var;
|
||||
struct {
|
||||
int64_t i;
|
||||
enum { INT_64BIT, INT_32BIT, INT_16BIT, INT_8BIT } precision;
|
||||
int64_t bits;
|
||||
} Int;
|
||||
struct {
|
||||
double n;
|
||||
enum { NUM_64BIT, NUM_32BIT } precision;
|
||||
int64_t bits;
|
||||
} Num;
|
||||
struct {
|
||||
CORD cord;
|
||||
|
@ -9,13 +9,14 @@
|
||||
#include <sys/param.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "../util.h"
|
||||
#include "../SipHash/halfsiphash.h"
|
||||
#include "../util.h"
|
||||
#include "bool.h"
|
||||
#include "types.h"
|
||||
|
||||
extern const void *SSS_HASH_VECTOR;
|
||||
|
||||
static CORD Bool__as_str(const bool *b, bool colorize, const TypeInfo *type)
|
||||
public CORD Bool__as_str(const bool *b, bool colorize, const TypeInfo *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!b) return "Bool";
|
||||
@ -25,9 +26,7 @@ static CORD Bool__as_str(const bool *b, bool colorize, const TypeInfo *type)
|
||||
return *b ? "yes" : "no";
|
||||
}
|
||||
|
||||
public struct {
|
||||
TypeInfo type;
|
||||
} Bool_type = {
|
||||
Bool_namespace_t Bool_type = {
|
||||
.type={
|
||||
.size=sizeof(bool),
|
||||
.align=alignof(bool),
|
||||
|
16
builtins/bool.h
Normal file
16
builtins/bool.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <gc/cord.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
CORD Bool__as_str(const bool *b, bool colorize, const TypeInfo *type);
|
||||
|
||||
typedef struct {
|
||||
TypeInfo type;
|
||||
} Bool_namespace_t;
|
||||
|
||||
extern Bool_namespace_t Bool_type;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
@ -1,10 +0,0 @@
|
||||
#include <gc.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "array.h"
|
||||
#include "types.h"
|
||||
#include "functions.h"
|
||||
#include "table.h"
|
||||
|
||||
public const char *SSS_HASH_VECTOR = "sss hash vector ----------------------------------------------";
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "../SipHash/halfsiphash.h"
|
||||
#include "array.h"
|
||||
#include "floats.h"
|
||||
#include "string.h"
|
||||
#include "types.h"
|
||||
|
||||
@ -23,12 +24,12 @@ public CORD Num__as_str(const double *f, bool colorize, const TypeInfo *type) {
|
||||
return c;
|
||||
}
|
||||
|
||||
static int32_t Num__compare(const double *x, const double *y, const TypeInfo *type) {
|
||||
public int32_t Num__compare(const double *x, const double *y, const TypeInfo *type) {
|
||||
(void)type;
|
||||
return (*x > *y) - (*x < *y);
|
||||
}
|
||||
|
||||
static bool Num__equal(const double *x, const double *y, const TypeInfo *type) {
|
||||
public bool Num__equal(const double *x, const double *y, const TypeInfo *type) {
|
||||
(void)type;
|
||||
return *x == *y;
|
||||
}
|
||||
@ -50,30 +51,7 @@ public bool Num__isinf(double n) { return isinf(n); }
|
||||
public bool Num__finite(double n) { return finite(n); }
|
||||
public bool Num__isnan(double n) { return isnan(n); }
|
||||
|
||||
typedef bool (*double_pred_t)(double);
|
||||
typedef double (*double_unary_fn_t)(double);
|
||||
typedef double (*double_binary_fn_t)(double, double);
|
||||
|
||||
public struct {
|
||||
TypeInfo type;
|
||||
// Constants:
|
||||
double NaN, _2_sqrt_pi, e, half_pi, inf, inverse_half_pi, inverse_pi, ln10, ln2,
|
||||
log2e, pi, quarter_pi, sqrt2, sqrt_half, tau;
|
||||
// Nullary functions:
|
||||
double (*random)(void);
|
||||
// Predicates:
|
||||
double_pred_t finite, isinf, isnan;
|
||||
// Unary functions:
|
||||
double_unary_fn_t abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, erf, erfc,
|
||||
exp, exp10, exp2, expm1, floor, j0, j1, log, log10, log1p, log2, logb,
|
||||
nextdown, nextup, rint, round, roundeven, significand, sin, sinh, sqrt,
|
||||
tan, tanh, tgamma, trunc, y0, y1;
|
||||
// Binary functions:
|
||||
double_binary_fn_t atan2, copysign, dist, hypot, maxmag, minmag, mod, nextafter, pow, remainder;
|
||||
// Odds and ends:
|
||||
CORD (*format)(double f, int64_t precision);
|
||||
CORD (*scientific)(double f, int64_t precision);
|
||||
} Num_type = {
|
||||
public Num_namespace_t Num_type = {
|
||||
.type=(TypeInfo){
|
||||
.size=sizeof(double),
|
||||
.align=alignof(double),
|
||||
@ -112,12 +90,12 @@ public CORD Num32__as_str(float *f, bool colorize, const TypeInfo *type) {
|
||||
return c;
|
||||
}
|
||||
|
||||
static int32_t Num32__compare(const float *x, const float *y, const TypeInfo *type) {
|
||||
public int32_t Num32__compare(const float *x, const float *y, const TypeInfo *type) {
|
||||
(void)type;
|
||||
return (*x > *y) - (*x < *y);
|
||||
}
|
||||
|
||||
static bool Num32__equal(const float *x, const float *y, const TypeInfo *type) {
|
||||
public bool Num32__equal(const float *x, const float *y, const TypeInfo *type) {
|
||||
(void)type;
|
||||
return *x == *y;
|
||||
}
|
||||
@ -143,30 +121,7 @@ public bool Num32__isinf(float n) { return isinf(n); }
|
||||
public bool Num32__finite(float n) { return finite(n); }
|
||||
public bool Num32__isnan(float n) { return isnan(n); }
|
||||
|
||||
typedef bool (*float_pred_t)(float);
|
||||
typedef float (*float_unary_fn_t)(float);
|
||||
typedef float (*float_binary_fn_t)(float, float);
|
||||
|
||||
public struct {
|
||||
TypeInfo type;
|
||||
// Alphabetized:
|
||||
float NaN, _2_sqrt_pi, e, half_pi, inf, inverse_half_pi, inverse_pi, ln10, ln2,
|
||||
log2e, pi, quarter_pi, sqrt2, sqrt_half, tau;
|
||||
// Nullary functions:
|
||||
float (*random)(void);
|
||||
// Predicates:
|
||||
float_pred_t finite, isinf, isnan;
|
||||
// Unary functions:
|
||||
float_unary_fn_t abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, erf, erfc,
|
||||
exp, exp10, exp2, expm1, floor, j0, j1, log, log10, log1p, log2, logb,
|
||||
nextdown, nextup, rint, round, roundeven, significand, sin, sinh, sqrt,
|
||||
tan, tanh, tgamma, trunc, y0, y1;
|
||||
// Binary functions:
|
||||
float_binary_fn_t atan2, copysign, dist, hypot, maxmag, minmag, mod, nextafter, pow, remainder;
|
||||
// Odds and ends:
|
||||
CORD (*format)(float f, int64_t precision);
|
||||
CORD (*scientific)(float f, int64_t precision);
|
||||
} Num32_type = {
|
||||
public Num32_namespace_t Num32_type = {
|
||||
.type=(TypeInfo){
|
||||
.size=sizeof(float),
|
||||
.align=alignof(float),
|
||||
|
83
builtins/floats.h
Normal file
83
builtins/floats.h
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#include <gc/cord.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
TypeInfo type;
|
||||
} Bool_namespace_t;
|
||||
|
||||
CORD Num__as_str(const double *f, bool colorize, const TypeInfo *type);
|
||||
int32_t Num__compare(const double *x, const double *y, const TypeInfo *type);
|
||||
bool Num__equal(const double *x, const double *y, const TypeInfo *type);
|
||||
CORD Num__format(double f, int64_t precision);
|
||||
CORD Num__scientific(double f, int64_t precision);
|
||||
double Num__mod(double num, double modulus);
|
||||
bool Num__isinf(double n);
|
||||
bool Num__finite(double n);
|
||||
bool Num__isnan(double n);
|
||||
|
||||
typedef bool (*double_pred_t)(double);
|
||||
typedef double (*double_unary_fn_t)(double);
|
||||
typedef double (*double_binary_fn_t)(double, double);
|
||||
|
||||
typedef struct {
|
||||
TypeInfo type;
|
||||
// Constants:
|
||||
double NaN, _2_sqrt_pi, e, half_pi, inf, inverse_half_pi, inverse_pi, ln10, ln2,
|
||||
log2e, pi, quarter_pi, sqrt2, sqrt_half, tau;
|
||||
// Nullary functions:
|
||||
double (*random)(void);
|
||||
// Predicates:
|
||||
double_pred_t finite, isinf, isnan;
|
||||
// Unary functions:
|
||||
double_unary_fn_t abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, erf, erfc,
|
||||
exp, exp10, exp2, expm1, floor, j0, j1, log, log10, log1p, log2, logb,
|
||||
nextdown, nextup, rint, round, roundeven, significand, sin, sinh, sqrt,
|
||||
tan, tanh, tgamma, trunc, y0, y1;
|
||||
// Binary functions:
|
||||
double_binary_fn_t atan2, copysign, dist, hypot, maxmag, minmag, mod, nextafter, pow, remainder;
|
||||
// Odds and ends:
|
||||
CORD (*format)(double f, int64_t precision);
|
||||
CORD (*scientific)(double f, int64_t precision);
|
||||
} Num_namespace_t;
|
||||
|
||||
CORD Num32__as_str(float *f, bool colorize, const TypeInfo *type);
|
||||
int32_t Num32__compare(const float *x, const float *y, const TypeInfo *type);
|
||||
bool Num32__equal(const float *x, const float *y, const TypeInfo *type);
|
||||
CORD Num32__format(float f, int64_t precision);
|
||||
CORD Num32__scientific(float f, int64_t precision);
|
||||
float Num32__mod(float num, float modulus);
|
||||
float Num32__random(void);
|
||||
bool Num32__isinf(float n);
|
||||
bool Num32__finite(float n);
|
||||
bool Num32__isnan(float n);
|
||||
|
||||
typedef bool (*float_pred_t)(float);
|
||||
typedef float (*float_unary_fn_t)(float);
|
||||
typedef float (*float_binary_fn_t)(float, float);
|
||||
|
||||
typedef struct {
|
||||
TypeInfo type;
|
||||
// Alphabetized:
|
||||
float NaN, _2_sqrt_pi, e, half_pi, inf, inverse_half_pi, inverse_pi, ln10, ln2,
|
||||
log2e, pi, quarter_pi, sqrt2, sqrt_half, tau;
|
||||
// Nullary functions:
|
||||
float (*random)(void);
|
||||
// Predicates:
|
||||
float_pred_t finite, isinf, isnan;
|
||||
// Unary functions:
|
||||
float_unary_fn_t abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, erf, erfc,
|
||||
exp, exp10, exp2, expm1, floor, j0, j1, log, log10, log1p, log2, logb,
|
||||
nextdown, nextup, rint, round, roundeven, significand, sin, sinh, sqrt,
|
||||
tan, tanh, tgamma, trunc, y0, y1;
|
||||
// Binary functions:
|
||||
float_binary_fn_t atan2, copysign, dist, hypot, maxmag, minmag, mod, nextafter, pow, remainder;
|
||||
// Odds and ends:
|
||||
CORD (*format)(float f, int64_t precision);
|
||||
CORD (*scientific)(float f, int64_t precision);
|
||||
} Num32_namespace_t;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
@ -17,7 +17,8 @@
|
||||
#include "types.h"
|
||||
|
||||
extern bool USE_COLOR;
|
||||
extern const void *SSS_HASH_VECTOR;
|
||||
|
||||
public const char *SSS_HASH_VECTOR = "sss hash vector ----------------------------------------------";;
|
||||
|
||||
public void fail(const char *fmt, ...)
|
||||
{
|
||||
|
@ -6,10 +6,12 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern const char *SSS_HASH_VECTOR;
|
||||
|
||||
void builtin_say(CORD str, CORD end);
|
||||
void builtin_fail(CORD fmt, ...);
|
||||
CORD builtin_last_err();
|
||||
void builtin_doctest(const char *label, CORD expr, const char *type, bool use_color, const char *expected, const char *filename, int start, int end);
|
||||
void __doctest(CORD label, void *expr, TypeInfo *type, CORD expected, const char *filename, int start, int end);
|
||||
|
||||
uint32_t generic_hash(const void *obj, const TypeInfo *type);
|
||||
int32_t generic_compare(const void *x, const void *y, const TypeInfo *type);
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
#include "../SipHash/halfsiphash.h"
|
||||
#include "array.h"
|
||||
#include "integers.h"
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
|
||||
extern const void *SSS_HASH_VECTOR;
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
||||
@ -48,15 +47,7 @@ extern const void *SSS_HASH_VECTOR;
|
||||
uint32_t r = arc4random_uniform((uint32_t)range); \
|
||||
return min + (c_type)r; \
|
||||
} \
|
||||
public struct { \
|
||||
TypeInfo type; \
|
||||
c_type min, max; \
|
||||
c_type (*abs)(c_type i); \
|
||||
CORD (*format)(c_type i, int64_t digits); \
|
||||
CORD (*hex)(c_type i, int64_t digits, bool uppercase, bool prefix); \
|
||||
CORD (*octal)(c_type i, int64_t digits, bool prefix); \
|
||||
c_type (*random)(int64_t min, int64_t max); \
|
||||
} KindOfInt##_type = { \
|
||||
public KindOfInt##_namespace_t KindOfInt##_type = { \
|
||||
.type={ \
|
||||
.size=sizeof(c_type), \
|
||||
.align=alignof(c_type), \
|
||||
@ -72,9 +63,10 @@ extern const void *SSS_HASH_VECTOR;
|
||||
.random=KindOfInt##__random, \
|
||||
};
|
||||
|
||||
DEFINE_INT_TYPE(int64_t, Int, "ld", labs, INT64_MIN, INT64_MAX);
|
||||
DEFINE_INT_TYPE(int64_t, Int64, "ld", labs, INT64_MIN, INT64_MAX);
|
||||
DEFINE_INT_TYPE(int32_t, Int32, "d_i32", abs, INT32_MIN, INT32_MAX);
|
||||
DEFINE_INT_TYPE(int16_t, Int16, "d_i16", abs, INT16_MIN, INT16_MAX);
|
||||
DEFINE_INT_TYPE(int8_t, Int8, "d_i8", abs, INT8_MIN, INT8_MAX);
|
||||
#undef DEFINE_INT_TYPE
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
30
builtins/integers.h
Normal file
30
builtins/integers.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <gc/cord.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define DEFINE_INT_TYPE(c_type, KindOfInt)\
|
||||
CORD KindOfInt ## __as_str(const c_type *i, bool colorize, const TypeInfo *type); \
|
||||
int32_t KindOfInt ## __compare(const c_type *x, const c_type *y, const TypeInfo *type); \
|
||||
CORD KindOfInt ## __format(c_type i, int64_t digits); \
|
||||
CORD KindOfInt ## __hex(c_type i, int64_t digits, bool uppercase, bool prefix); \
|
||||
CORD KindOfInt ## __octal(c_type i, int64_t digits, bool prefix); \
|
||||
c_type KindOfInt ## __random(int64_t min, int64_t max); \
|
||||
typedef struct { \
|
||||
TypeInfo type; \
|
||||
c_type min, max; \
|
||||
c_type (*abs)(c_type i); \
|
||||
CORD (*format)(c_type i, int64_t digits); \
|
||||
CORD (*hex)(c_type i, int64_t digits, bool uppercase, bool prefix); \
|
||||
CORD (*octal)(c_type i, int64_t digits, bool prefix); \
|
||||
c_type (*random)(int64_t min, int64_t max); \
|
||||
} KindOfInt##_namespace_t;
|
||||
DEFINE_INT_TYPE(int64_t, Int64);
|
||||
DEFINE_INT_TYPE(int32_t, Int32);
|
||||
DEFINE_INT_TYPE(int16_t, Int16);
|
||||
DEFINE_INT_TYPE(int8_t, Int8);
|
||||
#undef DEFINE_INT_TYPE
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
@ -40,7 +40,7 @@
|
||||
#define END_OF_CHAIN UINT32_MAX
|
||||
|
||||
#define GET_ENTRY(t, i) ((t)->entries.data + (t)->entries.stride*(i))
|
||||
#define ENTRY_TYPE(type) (&(TypeInfo){.size=entry_size(type), .align=entry_align(type), .tag=OpaqueInfo})
|
||||
#define ENTRIES_TYPE(type) (&(TypeInfo){.size=sizeof(array_t), .align=alignof(array_t), .tag=ArrayInfo, .ArrayInfo.item=(&(TypeInfo){.size=entry_size(type), .align=entry_align(type), .tag=OpaqueInfo})})
|
||||
|
||||
extern const void *SSS_HASH_VECTOR;
|
||||
|
||||
@ -102,7 +102,7 @@ static inline void hshow(const table_t *t)
|
||||
static void maybe_copy_on_write(table_t *t, const TypeInfo *type)
|
||||
{
|
||||
if (t->entries.copy_on_write) {
|
||||
Array__compact(&t->entries, ENTRY_TYPE(type));
|
||||
Array__compact(&t->entries, ENTRIES_TYPE(type));
|
||||
}
|
||||
|
||||
if (t->bucket_info && t->bucket_info->copy_on_write) {
|
||||
@ -279,7 +279,7 @@ public void *Table_reserve(table_t *t, const void *key, const void *value, const
|
||||
memcpy(buf + value_offset(type), value, value_size);
|
||||
else
|
||||
memset(buf + value_offset(type), 0, value_size);
|
||||
Array__insert(&t->entries, buf, 0, ENTRY_TYPE(type));
|
||||
Array__insert(&t->entries, buf, 0, ENTRIES_TYPE(type));
|
||||
|
||||
int64_t entry_index = t->entries.length-1;
|
||||
void *entry = GET_ENTRY(t, entry_index);
|
||||
@ -365,7 +365,7 @@ public void Table_remove(table_t *t, const void *key, const TypeInfo *type)
|
||||
// Last entry is being removed, so clear it out to be safe:
|
||||
memset(GET_ENTRY(t, last_entry), 0, entry_size(type));
|
||||
|
||||
Array__remove(&t->entries, t->entries.length, 1, ENTRY_TYPE(type));
|
||||
Array__remove(&t->entries, t->entries.length, 1, ENTRIES_TYPE(type));
|
||||
|
||||
int64_t bucket_to_clear;
|
||||
if (prev) { // Middle (or end) of a chain
|
||||
|
14
compile.c
14
compile.c
@ -41,11 +41,11 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
case Nil: return CORD_asprintf("(%r)NULL", compile_type(env, Match(ast, Nil)->type));
|
||||
case Bool: return Match(ast, Bool)->b ? "yes" : "no";
|
||||
case Var: return Match(ast, Var)->name;
|
||||
case Int: return CORD_asprintf("I%ld(%ld)", Match(ast, Int)->precision, Match(ast, Int)->i);
|
||||
case Int: return CORD_asprintf("I%ld(%ld)", Match(ast, Int)->bits, Match(ast, Int)->i);
|
||||
case Num: {
|
||||
// HACK: since the cord library doesn't support the '%a' specifier, this workaround
|
||||
// is necessary:
|
||||
char *buf = asprintfa(Match(ast, Num)->precision == 64 ? "%a" : "%af", Match(ast, Num)->n);
|
||||
char *buf = asprintfa(Match(ast, Num)->bits == 64 ? "%a" : "%af", Match(ast, Num)->n);
|
||||
return CORD_from_char_star(buf);
|
||||
}
|
||||
case Not: return CORD_asprintf("not(%r)", compile(env, Match(ast, Not)->value));
|
||||
@ -363,11 +363,15 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
if (test->expr->tag == Declare) {
|
||||
auto decl = Match(test->expr, Declare);
|
||||
return CORD_asprintf(
|
||||
"$var(%r, %r);\n$test(%r, %r, %r);",
|
||||
"$var(%r, %r);\n"
|
||||
"__doctest(\"=\", &%r, %r, %r, %r, %ld, %ld);",
|
||||
compile(env, decl->var), compile(env, decl->value),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(env, decl->var),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
compile_type_info(env, get_type(env, decl->value)),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->expr->file->filename)),
|
||||
(int64_t)(test->expr->start - test->expr->file->text),
|
||||
(int64_t)(test->expr->end - test->expr->file->text));
|
||||
} else if (test->expr->tag == Assign) {
|
||||
auto assign = Match(test->expr, Assign);
|
||||
CORD code = "{ // Assignment\n";
|
||||
|
@ -10,5 +10,6 @@
|
||||
CORD compile_type(env_t *env, type_ast_t *t);
|
||||
CORD compile(env_t *env, ast_t *ast);
|
||||
CORD compile_statement(env_t *env, ast_t *ast);
|
||||
CORD compile_type_info(env_t *env, type_t *t);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -94,8 +94,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
const char *ldflags = "-Wl,-rpath '-Wl,$ORIGIN'";
|
||||
|
||||
const char *run = heap_strf("tcc -run %s %s %s -", cflags, ldflags, ldlibs);
|
||||
// const char *run = heap_strf("gcc -x c %s %s %s - -o program && ./program", cflags, ldflags, ldlibs);
|
||||
// const char *run = heap_strf("tcc -run %s %s %s -", cflags, ldflags, ldlibs);
|
||||
const char *run = heap_strf("gcc -x c %s %s %s - -o program && ./program", cflags, ldflags, ldlibs);
|
||||
FILE *cc = popen(run, "w");
|
||||
CORD_put(program, cc);
|
||||
fclose(cc);
|
||||
|
@ -11,7 +11,13 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins/array.h"
|
||||
#include "builtins/datatypes.h"
|
||||
#include "builtins/functions.h"
|
||||
#include "builtins/pointer.h"
|
||||
#include "builtins/string.h"
|
||||
#include "builtins/table.h"
|
||||
#include "builtins/types.h"
|
||||
|
||||
#define Int64_t int64_t
|
||||
#define Int32_t int32_t
|
||||
|
24
parse.c
24
parse.c
@ -420,19 +420,19 @@ PARSER(parse_int) {
|
||||
|
||||
if (match(&pos, "%")) {
|
||||
double d = (double)i / 100.;
|
||||
return NewAST(ctx->file, start, pos, Num, .n=d, .precision=64);
|
||||
return NewAST(ctx->file, start, pos, Num, .n=d, .bits=64);
|
||||
}
|
||||
|
||||
match(&pos, "_");
|
||||
int64_t precision = 64;
|
||||
if (match(&pos, "i64")) precision = 64;
|
||||
else if (match(&pos, "i32")) precision = 32;
|
||||
else if (match(&pos, "i16")) precision = 16;
|
||||
else if (match(&pos, "i8")) precision = 8;
|
||||
int64_t bits = 64;
|
||||
if (match(&pos, "i64")) bits = 64;
|
||||
else if (match(&pos, "i32")) bits = 32;
|
||||
else if (match(&pos, "i16")) bits = 16;
|
||||
else if (match(&pos, "i8")) bits = 8;
|
||||
|
||||
// else if (match(&pos, ".") || match(&pos, "e")) return NULL; // looks like a float
|
||||
|
||||
return NewAST(ctx->file, start, pos, Int, .i=i, .precision=precision);
|
||||
return NewAST(ctx->file, start, pos, Int, .i=i, .bits=bits);
|
||||
}
|
||||
|
||||
type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
|
||||
@ -558,16 +558,16 @@ PARSER(parse_num) {
|
||||
|
||||
if (negative) d *= -1;
|
||||
|
||||
int64_t precision = 64;
|
||||
int64_t bits = 64;
|
||||
match(&pos, "_");
|
||||
if (match(&pos, "f64")) precision = 64;
|
||||
else if (match(&pos, "f32")) precision = 32;
|
||||
if (match(&pos, "f64")) bits = 64;
|
||||
else if (match(&pos, "f32")) bits = 32;
|
||||
|
||||
if (match(&pos, "%")) {
|
||||
d /= 100.;
|
||||
}
|
||||
|
||||
return NewAST(ctx->file, start, pos, Num, .n=d, .precision=precision);
|
||||
return NewAST(ctx->file, start, pos, Num, .n=d, .bits=bits);
|
||||
}
|
||||
|
||||
static inline bool match_separator(const char **pos) { // Either comma or newline
|
||||
@ -1606,7 +1606,7 @@ PARSER(parse_func_def) {
|
||||
if (match_word(&pos, "inline")) {
|
||||
is_inline = true;
|
||||
} else if (match_word(&pos, "cached")) {
|
||||
if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .i=INT64_MAX, .precision=64);
|
||||
if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .i=INT64_MAX, .bits=64);
|
||||
} else if (match_word(&pos, "cache_size")) {
|
||||
if (whitespace(&pos), !match(&pos, "="))
|
||||
parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
|
||||
|
14
typecheck.c
14
typecheck.c
@ -133,21 +133,11 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
}
|
||||
case Int: {
|
||||
auto i = Match(ast, Int);
|
||||
switch (i->precision) {
|
||||
case INT_64BIT: return Type(IntType, .bits=64);
|
||||
case INT_32BIT: return Type(IntType, .bits=32);
|
||||
case INT_16BIT: return Type(IntType, .bits=16);
|
||||
case INT_8BIT: return Type(IntType, .bits=8);
|
||||
default: code_err(ast, "Unsupported precision");
|
||||
}
|
||||
return Type(IntType, .bits=i->bits);
|
||||
}
|
||||
case Num: {
|
||||
auto n = Match(ast, Num);
|
||||
switch (n->precision) {
|
||||
case NUM_64BIT: return Type(NumType, .bits=64);
|
||||
case NUM_32BIT: return Type(NumType, .bits=32);
|
||||
default: code_err(ast, "Unsupported precision");
|
||||
}
|
||||
return Type(NumType, .bits=n->bits);
|
||||
}
|
||||
case HeapAllocate: {
|
||||
type_t *pointed = get_type(env, Match(ast, HeapAllocate)->value);
|
||||
|
Loading…
Reference in New Issue
Block a user