first commit
This commit is contained in:
commit
21f61cdf76
30 changed files with 1687 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.o
|
||||||
|
compiler
|
||||||
|
example
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "slibs"]
|
||||||
|
path = slibs
|
||||||
|
url = https://git.samahh.dev/sam/slibs
|
21
Makefile
Normal file
21
Makefile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
BINARY=compiler
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-O3 -Iinclude
|
||||||
|
LDFLAGS=-Llib -ltcc
|
||||||
|
|
||||||
|
CFILES=$(shell find -L src -type f -name '*.c')
|
||||||
|
OBJ=$(CFILES:.c=.o)
|
||||||
|
|
||||||
|
$(BINARY): $(OBJ) Makefile
|
||||||
|
$(CC) $(OBJ) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
run: $(BINARY)
|
||||||
|
./$(BINARY) example.lisp example
|
||||||
|
./example
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJ) $(BINARY) example
|
1
example.lisp
Executable file
1
example.lisp
Executable file
|
@ -0,0 +1 @@
|
||||||
|
(print_str "guh")
|
37
include/ast.h
Normal file
37
include/ast.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include <slibs/slibs.h>
|
||||||
|
#include <tokenizer.h>
|
||||||
|
|
||||||
|
#ifndef __AST_H__
|
||||||
|
#define __AST_H__
|
||||||
|
|
||||||
|
extern const char* ASTTypeText[];
|
||||||
|
|
||||||
|
typedef enum ASTType {
|
||||||
|
AST_PROGRAM,
|
||||||
|
AST_CALL_EXPRESSION,
|
||||||
|
AST_NUMBER_LITERAL,
|
||||||
|
AST_STRING_LITERAL
|
||||||
|
} ASTType;
|
||||||
|
|
||||||
|
typedef sl_vec(struct ASTNode*) ASTVec;
|
||||||
|
|
||||||
|
typedef struct ASTNode {
|
||||||
|
ASTType type;
|
||||||
|
const char* name;
|
||||||
|
const char* value;
|
||||||
|
|
||||||
|
ASTVec body;
|
||||||
|
ASTVec params;
|
||||||
|
} ASTNode;
|
||||||
|
|
||||||
|
ASTNode* ast_parse(Token** token);
|
||||||
|
ASTNode* ast_walk(Token** token);
|
||||||
|
void ast_print(ASTNode* node, int indent);
|
||||||
|
void ast_step(Token** token);
|
||||||
|
ASTNode* ast_create_empty(ASTType type);
|
||||||
|
ASTNode* ast_create_program(ASTVec body);
|
||||||
|
ASTNode* ast_create_call_expression(const char* name, ASTVec params);
|
||||||
|
ASTNode* ast_create_number_literal(const char* value);
|
||||||
|
ASTNode* ast_create_string_literal(const char* value);
|
||||||
|
|
||||||
|
#endif
|
8
include/codegen.h
Normal file
8
include/codegen.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include <ast.h>
|
||||||
|
|
||||||
|
#ifndef __CODEGEN_H__
|
||||||
|
#define __CODEGEN_H__
|
||||||
|
|
||||||
|
const char* codegen(ASTNode* node);
|
||||||
|
|
||||||
|
#endif
|
18
include/regexp.h
Normal file
18
include/regexp.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include <regex.h>
|
||||||
|
#include <slibs/slibs.h>
|
||||||
|
|
||||||
|
#ifndef __REGEXP_H__
|
||||||
|
#define __REGEXP_H__
|
||||||
|
|
||||||
|
typedef int (*match_func)(regex_t, char, char**);
|
||||||
|
|
||||||
|
regex_t regex_create(const char* pattern, int flags);
|
||||||
|
int match_char(regex_t regex, char c);
|
||||||
|
sl_string collect_until(match_func matcher, regex_t regex, char** input);
|
||||||
|
sl_string collect_until_match(regex_t regex, char** input);
|
||||||
|
sl_string collect_until_no_match(regex_t regex, char** input);
|
||||||
|
sl_string collect_until_match_escapable(regex_t regex, char** input);
|
||||||
|
sl_string collect_until_no_match_escapable(regex_t regex, char** input);
|
||||||
|
void regex_step(char** input, char* c);
|
||||||
|
|
||||||
|
#endif
|
208
include/slibs/slibs.h
Normal file
208
include/slibs/slibs.h
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
#ifndef SLIBS_H
|
||||||
|
#define SLIBS_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
|
|
||||||
|
#define sl_auto(name, x) typeof(x) name = x
|
||||||
|
|
||||||
|
#define sl_new(type, ...) \
|
||||||
|
({ \
|
||||||
|
type *ptr = malloc(sizeof(type)); \
|
||||||
|
*ptr = (type){__VA_ARGS__}; \
|
||||||
|
ptr; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define sl_init(type, ...) \
|
||||||
|
(type) { __VA_ARGS__ }
|
||||||
|
|
||||||
|
#define sl_array_len(arr) sizeof(arr) / sizeof(arr[0])
|
||||||
|
|
||||||
|
#define sl_fmt_spec(arg) \
|
||||||
|
_Generic((arg), \
|
||||||
|
int8_t: "%d", \
|
||||||
|
int16_t: "%d", \
|
||||||
|
int32_t: "%d", \
|
||||||
|
int64_t: "%lld", \
|
||||||
|
uint8_t: "%u", \
|
||||||
|
uint16_t: "%u", \
|
||||||
|
uint32_t: "%lu", \
|
||||||
|
uint64_t: "%llu", \
|
||||||
|
double: "%lf", \
|
||||||
|
float: "%f", \
|
||||||
|
char: "%c", \
|
||||||
|
char *: "%s", \
|
||||||
|
void *: "%p", \
|
||||||
|
default: "Unknown")
|
||||||
|
|
||||||
|
#define sl_stringify(x) #x
|
||||||
|
|
||||||
|
// Vector
|
||||||
|
|
||||||
|
#define sl_vec(type) \
|
||||||
|
struct \
|
||||||
|
{ \
|
||||||
|
type *data; \
|
||||||
|
size_t size; \
|
||||||
|
size_t capacity; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_vec_grow(vec) \
|
||||||
|
{ \
|
||||||
|
(vec).capacity = (vec).capacity * 2 + 1; \
|
||||||
|
void *ptr = realloc((vec).data, (vec).capacity * sizeof(*(vec).data)); \
|
||||||
|
if (ptr) \
|
||||||
|
(vec).data = ptr; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_vec_push(vec, element) \
|
||||||
|
{ \
|
||||||
|
if ((vec).size >= (vec).capacity) \
|
||||||
|
sl_vec_grow(vec); \
|
||||||
|
(vec).data[(vec).size++] = (element); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_vec_shift(vec, element) \
|
||||||
|
{ \
|
||||||
|
if ((vec).size >= (vec).capacity) \
|
||||||
|
sl_vec_grow(vec); \
|
||||||
|
memmove((vec).data + 1, (vec).data, (vec).size * sizeof(*(vec).data)); \
|
||||||
|
(vec).data[0] = (element); \
|
||||||
|
(vec).size++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_vec_pop(vec) \
|
||||||
|
{ \
|
||||||
|
if ((vec).size > 0) \
|
||||||
|
{ \
|
||||||
|
(vec).size--; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_vec_at(vec, index) ((vec).data[index])
|
||||||
|
|
||||||
|
#define sl_vec_size(vec) ((vec).size)
|
||||||
|
|
||||||
|
#define sl_vec_capacity(vec) ((vec).capacity)
|
||||||
|
|
||||||
|
#define sl_vec_free(vec) free((vec).data)
|
||||||
|
|
||||||
|
#define sl_vec_begin(vec) (vec).data
|
||||||
|
|
||||||
|
#define sl_vec_end(vec) ((vec).data + (vec).size)
|
||||||
|
|
||||||
|
#define sl_vec_it(name, vec) \
|
||||||
|
sl_auto((name), sl_vec_begin(vec)); \
|
||||||
|
(name) != sl_vec_end(vec); \
|
||||||
|
++(name)
|
||||||
|
|
||||||
|
// String
|
||||||
|
|
||||||
|
typedef sl_vec(char) sl_string;
|
||||||
|
|
||||||
|
#define sl_string(c_str) \
|
||||||
|
({ \
|
||||||
|
sl_string str = {0}; \
|
||||||
|
for (size_t i = 0; i < strlen((c_str)); i++) \
|
||||||
|
sl_vec_push(str, (c_str)[i]); \
|
||||||
|
str; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define sl_tostring(val) \
|
||||||
|
({ \
|
||||||
|
sl_auto(len, snprintf(NULL, 0, sl_fmt_spec(val), val) + 1); \
|
||||||
|
sl_auto(buf, (char *)malloc(len)); \
|
||||||
|
snprintf(buf, len, sl_fmt_spec(val), val); \
|
||||||
|
sl_auto(str, sl_string(buf)); \
|
||||||
|
free(buf); \
|
||||||
|
str; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define sl_str_free(str) sl_vec_free(str)
|
||||||
|
|
||||||
|
#define sl_c_str(str) \
|
||||||
|
({ \
|
||||||
|
sl_vec_push((str), '\0'); \
|
||||||
|
(str).size--; \
|
||||||
|
(str).data; \
|
||||||
|
})
|
||||||
|
|
||||||
|
void sl_append_c_str(sl_string* sl_str, const char* c_str);
|
||||||
|
|
||||||
|
#ifdef SL_IMPLEMENTATION
|
||||||
|
void sl_append_c_str(sl_string* sl_str, const char* c_str) {
|
||||||
|
for(int i = 0; i < strlen(c_str); i++) {
|
||||||
|
sl_vec_push(*sl_str, c_str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Pointers
|
||||||
|
|
||||||
|
#define sl_ptr(type) \
|
||||||
|
struct \
|
||||||
|
{ \
|
||||||
|
type *ptr; \
|
||||||
|
int ref_count; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_ptr_make(raw_ptr) \
|
||||||
|
{ \
|
||||||
|
raw_ptr, 1 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sl_ptr_release(smart_ptr) \
|
||||||
|
({ \
|
||||||
|
smart_ptr.ref_count--; \
|
||||||
|
if (smart_ptr.ref_count <= 0) \
|
||||||
|
{ \
|
||||||
|
free(smart_ptr.ptr); \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define sl_ptr_get(smart_ptr, raw_ptr_name, scope) \
|
||||||
|
({ \
|
||||||
|
assert(smart_ptr.ref_count > 0 && "Smart pointer already released!"); \
|
||||||
|
sl_auto(raw_ptr_name, smart_ptr.ptr); \
|
||||||
|
smart_ptr.ref_count++; \
|
||||||
|
scope; \
|
||||||
|
sl_ptr_release(smart_ptr); \
|
||||||
|
});
|
||||||
|
|
||||||
|
#define sl_ptr_scope(smart_ptr, scope) \
|
||||||
|
({ \
|
||||||
|
scope; \
|
||||||
|
sl_ptr_release(smart_ptr); \
|
||||||
|
});
|
||||||
|
|
||||||
|
void sl_read_file(const char *filename, sl_string *buffer);
|
||||||
|
|
||||||
|
#ifdef SL_IMPLEMENTATION
|
||||||
|
void sl_read_file(const char *filename, sl_string *buffer)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(filename, "r");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: could not open file %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
size_t file_size = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < file_size; i++)
|
||||||
|
{
|
||||||
|
sl_vec_push(*buffer, fgetc(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SLIBS_H
|
116
include/tcc/libtcc.h
Normal file
116
include/tcc/libtcc.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#ifndef LIBTCC_H
|
||||||
|
#define LIBTCC_H
|
||||||
|
|
||||||
|
#ifndef LIBTCCAPI
|
||||||
|
# define LIBTCCAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* set custom allocator for all allocations (optional), NULL for default. */
|
||||||
|
typedef void *TCCReallocFunc(void *ptr, unsigned long size);
|
||||||
|
LIBTCCAPI void tcc_set_realloc(TCCReallocFunc *my_realloc);
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
typedef struct TCCState TCCState;
|
||||||
|
|
||||||
|
/* create a new TCC compilation context */
|
||||||
|
LIBTCCAPI TCCState *tcc_new(void);
|
||||||
|
|
||||||
|
/* free a TCC compilation context */
|
||||||
|
LIBTCCAPI void tcc_delete(TCCState *s);
|
||||||
|
|
||||||
|
/* set CONFIG_TCCDIR at runtime */
|
||||||
|
LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
|
||||||
|
|
||||||
|
/* set error/warning callback (optional) */
|
||||||
|
typedef void TCCErrorFunc(void *opaque, const char *msg);
|
||||||
|
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func);
|
||||||
|
|
||||||
|
/* set options as from command line (multiple supported) */
|
||||||
|
LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* preprocessor */
|
||||||
|
|
||||||
|
/* add include path */
|
||||||
|
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
|
||||||
|
|
||||||
|
/* add in system include path */
|
||||||
|
LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
|
||||||
|
|
||||||
|
/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */
|
||||||
|
LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
|
||||||
|
|
||||||
|
/* undefine preprocess symbol 'sym' */
|
||||||
|
LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* compiling */
|
||||||
|
|
||||||
|
/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
|
||||||
|
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
|
||||||
|
|
||||||
|
/* compile a string containing a C source. Return -1 if error. */
|
||||||
|
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
|
||||||
|
|
||||||
|
/* Tip: to have more specific errors/warnings from tcc_compile_string(),
|
||||||
|
you can prefix the string with "#line <num> \"<filename>\"\n" */
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* linking commands */
|
||||||
|
|
||||||
|
/* set output type. MUST BE CALLED before any compilation */
|
||||||
|
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
|
||||||
|
#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory */
|
||||||
|
#define TCC_OUTPUT_EXE 2 /* executable file */
|
||||||
|
#define TCC_OUTPUT_DLL 4 /* dynamic library */
|
||||||
|
#define TCC_OUTPUT_OBJ 3 /* object file */
|
||||||
|
#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */
|
||||||
|
|
||||||
|
/* equivalent to -Lpath option */
|
||||||
|
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
|
||||||
|
|
||||||
|
/* the library name is the same as the argument of the '-l' option */
|
||||||
|
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
|
||||||
|
|
||||||
|
/* add a symbol to the compiled program */
|
||||||
|
LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
|
||||||
|
|
||||||
|
/* output an executable, library or object file. DO NOT call
|
||||||
|
tcc_relocate() before. */
|
||||||
|
LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
|
||||||
|
|
||||||
|
/* link and run main() function and return its value. DO NOT call
|
||||||
|
tcc_relocate() before. */
|
||||||
|
LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
|
||||||
|
|
||||||
|
/* do all relocations (needed before using tcc_get_symbol()) */
|
||||||
|
LIBTCCAPI int tcc_relocate(TCCState *s1);
|
||||||
|
|
||||||
|
/* return symbol value or NULL if not found */
|
||||||
|
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
|
||||||
|
|
||||||
|
/* list all (global) symbols and their values via 'symbol_cb()' */
|
||||||
|
LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
|
||||||
|
void (*symbol_cb)(void *ctx, const char *name, const void *val));
|
||||||
|
|
||||||
|
/* experimental/advanced section (see libtcc_test_mt.c for an example) */
|
||||||
|
|
||||||
|
/* catch runtime exceptions (optionally limit backtraces at top_func),
|
||||||
|
when using tcc_set_options("-bt") and when not using tcc_run() */
|
||||||
|
LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);
|
||||||
|
#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))
|
||||||
|
|
||||||
|
/* custom error printer for runtime exceptions. Returning 0 stops backtrace */
|
||||||
|
typedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);
|
||||||
|
LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
25
include/tokenizer.h
Normal file
25
include/tokenizer.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef __TOKENIZER_H__
|
||||||
|
#define __TOKENIZER_H__
|
||||||
|
|
||||||
|
extern const char* TokenTypeText[];
|
||||||
|
|
||||||
|
typedef enum TokenType {
|
||||||
|
TOKEN_LPAREN,
|
||||||
|
TOKEN_RPAREN,
|
||||||
|
TOKEN_NUMBER,
|
||||||
|
TOKEN_NAME,
|
||||||
|
TOKEN_STRING
|
||||||
|
} TokenType;
|
||||||
|
|
||||||
|
typedef struct Token {
|
||||||
|
char* value;
|
||||||
|
TokenType type;
|
||||||
|
struct Token* next;
|
||||||
|
} Token;
|
||||||
|
|
||||||
|
Token* tokenize(char* input);
|
||||||
|
|
||||||
|
Token* token_create(char* value, TokenType type, Token* root);
|
||||||
|
Token* token_append(Token* root, Token* new_token);
|
||||||
|
|
||||||
|
#endif
|
BIN
lib/libtcc.a
Normal file
BIN
lib/libtcc.a
Normal file
Binary file not shown.
75
lib/tcc/include/float.h
Normal file
75
lib/tcc/include/float.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef _FLOAT_H_
|
||||||
|
#define _FLOAT_H_
|
||||||
|
|
||||||
|
#define FLT_RADIX 2
|
||||||
|
|
||||||
|
/* IEEE float */
|
||||||
|
#define FLT_MANT_DIG 24
|
||||||
|
#define FLT_DIG 6
|
||||||
|
#define FLT_ROUNDS 1
|
||||||
|
#define FLT_EPSILON 1.19209290e-07F
|
||||||
|
#define FLT_MIN_EXP (-125)
|
||||||
|
#define FLT_MIN 1.17549435e-38F
|
||||||
|
#define FLT_MIN_10_EXP (-37)
|
||||||
|
#define FLT_MAX_EXP 128
|
||||||
|
#define FLT_MAX 3.40282347e+38F
|
||||||
|
#define FLT_MAX_10_EXP 38
|
||||||
|
|
||||||
|
/* IEEE double */
|
||||||
|
#define DBL_MANT_DIG 53
|
||||||
|
#define DBL_DIG 15
|
||||||
|
#define DBL_EPSILON 2.2204460492503131e-16
|
||||||
|
#define DBL_MIN_EXP (-1021)
|
||||||
|
#define DBL_MIN 2.2250738585072014e-308
|
||||||
|
#define DBL_MIN_10_EXP (-307)
|
||||||
|
#define DBL_MAX_EXP 1024
|
||||||
|
#define DBL_MAX 1.7976931348623157e+308
|
||||||
|
#define DBL_MAX_10_EXP 308
|
||||||
|
|
||||||
|
/* horrible intel long double */
|
||||||
|
#if defined __i386__ || defined __x86_64__
|
||||||
|
|
||||||
|
#define LDBL_MANT_DIG 64
|
||||||
|
#define LDBL_DIG 18
|
||||||
|
#define LDBL_EPSILON 1.08420217248550443401e-19L
|
||||||
|
#define LDBL_MIN_EXP (-16381)
|
||||||
|
#define LDBL_MIN 3.36210314311209350626e-4932L
|
||||||
|
#define LDBL_MIN_10_EXP (-4931)
|
||||||
|
#define LDBL_MAX_EXP 16384
|
||||||
|
#define LDBL_MAX 1.18973149535723176502e+4932L
|
||||||
|
#define LDBL_MAX_10_EXP 4932
|
||||||
|
#define DECIMAL_DIG 21
|
||||||
|
|
||||||
|
#elif defined __aarch64__ || defined __riscv
|
||||||
|
/*
|
||||||
|
* Use values from:
|
||||||
|
* gcc -dM -E -xc /dev/null | grep LDBL | sed -e "s/__//g"
|
||||||
|
*/
|
||||||
|
#define LDBL_MANT_DIG 113
|
||||||
|
#define LDBL_DIG 33
|
||||||
|
#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
|
||||||
|
#define LDBL_MIN_EXP (-16381)
|
||||||
|
#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
|
||||||
|
#define LDBL_MIN_10_EXP (-4931)
|
||||||
|
#define LDBL_MAX_EXP 16384
|
||||||
|
#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
|
||||||
|
#define LDBL_MAX_EXP 16384
|
||||||
|
#define DECIMAL_DIG 36
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* same as IEEE double */
|
||||||
|
#define LDBL_MANT_DIG 53
|
||||||
|
#define LDBL_DIG 15
|
||||||
|
#define LDBL_EPSILON 2.2204460492503131e-16L
|
||||||
|
#define LDBL_MIN_EXP (-1021)
|
||||||
|
#define LDBL_MIN 2.2250738585072014e-308L
|
||||||
|
#define LDBL_MIN_10_EXP (-307)
|
||||||
|
#define LDBL_MAX_EXP 1024
|
||||||
|
#define LDBL_MAX 1.7976931348623157e+308L
|
||||||
|
#define LDBL_MAX_10_EXP 308
|
||||||
|
#define DECIMAL_DIG 17
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FLOAT_H_ */
|
16
lib/tcc/include/stdalign.h
Normal file
16
lib/tcc/include/stdalign.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef _STDALIGN_H
|
||||||
|
#define _STDALIGN_H
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ < 201112L && (defined(__GNUC__) || defined(__TINYC__))
|
||||||
|
# define _Alignas(t) __attribute__((__aligned__(t)))
|
||||||
|
# define _Alignof(t) __alignof__(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define alignas _Alignas
|
||||||
|
#define alignof _Alignof
|
||||||
|
|
||||||
|
#define __alignas_is_defined 1
|
||||||
|
#define __alignof_is_defined 1
|
||||||
|
|
||||||
|
#endif /* _STDALIGN_H */
|
||||||
|
|
14
lib/tcc/include/stdarg.h
Normal file
14
lib/tcc/include/stdarg.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef _STDARG_H
|
||||||
|
#define _STDARG_H
|
||||||
|
|
||||||
|
typedef __builtin_va_list va_list;
|
||||||
|
#define va_start __builtin_va_start
|
||||||
|
#define va_arg __builtin_va_arg
|
||||||
|
#define va_copy __builtin_va_copy
|
||||||
|
#define va_end __builtin_va_end
|
||||||
|
|
||||||
|
/* fix a buggy dependency on GCC in libio.h */
|
||||||
|
typedef va_list __gnuc_va_list;
|
||||||
|
#define _VA_LIST_DEFINED
|
||||||
|
|
||||||
|
#endif /* _STDARG_H */
|
173
lib/tcc/include/stdatomic.h
Normal file
173
lib/tcc/include/stdatomic.h
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/* This file is derived from clang's stdatomic.h */
|
||||||
|
|
||||||
|
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===-----------------------------------------------------------------------===
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STDATOMIC_H
|
||||||
|
#define _STDATOMIC_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define __ATOMIC_RELAXED 0
|
||||||
|
#define __ATOMIC_CONSUME 1
|
||||||
|
#define __ATOMIC_ACQUIRE 2
|
||||||
|
#define __ATOMIC_RELEASE 3
|
||||||
|
#define __ATOMIC_ACQ_REL 4
|
||||||
|
#define __ATOMIC_SEQ_CST 5
|
||||||
|
|
||||||
|
/* Memory ordering */
|
||||||
|
typedef enum {
|
||||||
|
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||||
|
memory_order_consume = __ATOMIC_CONSUME,
|
||||||
|
memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||||
|
memory_order_release = __ATOMIC_RELEASE,
|
||||||
|
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||||
|
memory_order_seq_cst = __ATOMIC_SEQ_CST,
|
||||||
|
} memory_order;
|
||||||
|
|
||||||
|
/* Atomic typedefs */
|
||||||
|
typedef _Atomic(_Bool) atomic_bool;
|
||||||
|
typedef _Atomic(char) atomic_char;
|
||||||
|
typedef _Atomic(signed char) atomic_schar;
|
||||||
|
typedef _Atomic(unsigned char) atomic_uchar;
|
||||||
|
typedef _Atomic(short) atomic_short;
|
||||||
|
typedef _Atomic(unsigned short) atomic_ushort;
|
||||||
|
typedef _Atomic(int) atomic_int;
|
||||||
|
typedef _Atomic(unsigned int) atomic_uint;
|
||||||
|
typedef _Atomic(long) atomic_long;
|
||||||
|
typedef _Atomic(unsigned long) atomic_ulong;
|
||||||
|
typedef _Atomic(long long) atomic_llong;
|
||||||
|
typedef _Atomic(unsigned long long) atomic_ullong;
|
||||||
|
typedef _Atomic(uint_least16_t) atomic_char16_t;
|
||||||
|
typedef _Atomic(uint_least32_t) atomic_char32_t;
|
||||||
|
typedef _Atomic(wchar_t) atomic_wchar_t;
|
||||||
|
typedef _Atomic(int_least8_t) atomic_int_least8_t;
|
||||||
|
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
|
||||||
|
typedef _Atomic(int_least16_t) atomic_int_least16_t;
|
||||||
|
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
|
||||||
|
typedef _Atomic(int_least32_t) atomic_int_least32_t;
|
||||||
|
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
|
||||||
|
typedef _Atomic(int_least64_t) atomic_int_least64_t;
|
||||||
|
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
|
||||||
|
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
|
||||||
|
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
|
||||||
|
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
|
||||||
|
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
|
||||||
|
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
|
||||||
|
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
|
||||||
|
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
|
||||||
|
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
|
||||||
|
typedef _Atomic(intptr_t) atomic_intptr_t;
|
||||||
|
typedef _Atomic(uintptr_t) atomic_uintptr_t;
|
||||||
|
typedef _Atomic(size_t) atomic_size_t;
|
||||||
|
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
|
||||||
|
typedef _Atomic(intmax_t) atomic_intmax_t;
|
||||||
|
typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
||||||
|
|
||||||
|
/* Atomic flag */
|
||||||
|
typedef struct {
|
||||||
|
atomic_bool value;
|
||||||
|
} atomic_flag;
|
||||||
|
|
||||||
|
#define ATOMIC_FLAG_INIT {0}
|
||||||
|
#define ATOMIC_VAR_INIT(value) (value)
|
||||||
|
|
||||||
|
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||||
|
__atomic_test_and_set((void *)(&((object)->value)), order)
|
||||||
|
#define atomic_flag_test_and_set(object) \
|
||||||
|
atomic_flag_test_and_set_explicit(object, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_flag_clear_explicit(object, order) \
|
||||||
|
__atomic_clear((bool *)(&((object)->value)), order)
|
||||||
|
#define atomic_flag_clear(object) \
|
||||||
|
atomic_flag_clear_explicit(object, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
/* Generic routines */
|
||||||
|
#define atomic_init(object, desired) \
|
||||||
|
atomic_store_explicit(object, desired, __ATOMIC_RELAXED)
|
||||||
|
|
||||||
|
#define atomic_store_explicit(object, desired, order) \
|
||||||
|
({ __typeof__ (object) ptr = (object); \
|
||||||
|
__typeof__ (*ptr) tmp = (desired); \
|
||||||
|
__atomic_store (ptr, &tmp, (order)); \
|
||||||
|
})
|
||||||
|
#define atomic_store(object, desired) \
|
||||||
|
atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_load_explicit(object, order) \
|
||||||
|
({ __typeof__ (object) ptr = (object); \
|
||||||
|
__typeof__ (*ptr) tmp; \
|
||||||
|
__atomic_load (ptr, &tmp, (order)); \
|
||||||
|
tmp; \
|
||||||
|
})
|
||||||
|
#define atomic_load(object) atomic_load_explicit (object, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_exchange_explicit(object, desired, order) \
|
||||||
|
({ __typeof__ (object) ptr = (object); \
|
||||||
|
__typeof__ (*ptr) val = (desired); \
|
||||||
|
__typeof__ (*ptr) tmp; \
|
||||||
|
__atomic_exchange (ptr, &val, &tmp, (order)); \
|
||||||
|
tmp; \
|
||||||
|
})
|
||||||
|
#define atomic_exchange(object, desired) \
|
||||||
|
atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||||
|
({ __typeof__ (object) ptr = (object); \
|
||||||
|
__typeof__ (*ptr) tmp = desired; \
|
||||||
|
__atomic_compare_exchange(ptr, expected, &tmp, 0, success, failure); \
|
||||||
|
})
|
||||||
|
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||||
|
atomic_compare_exchange_strong_explicit (object, expected, desired, \
|
||||||
|
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||||
|
({ __typeof__ (object) ptr = (object); \
|
||||||
|
__typeof__ (*ptr) tmp = desired; \
|
||||||
|
__atomic_compare_exchange(ptr, expected, &tmp, 1, success, failure); \
|
||||||
|
})
|
||||||
|
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||||
|
atomic_compare_exchange_weak_explicit (object, expected, desired, \
|
||||||
|
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#define atomic_fetch_add(object, operand) \
|
||||||
|
__atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_fetch_add_explicit __atomic_fetch_add
|
||||||
|
|
||||||
|
#define atomic_fetch_sub(object, operand) \
|
||||||
|
__atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_fetch_sub_explicit __atomic_fetch_sub
|
||||||
|
|
||||||
|
#define atomic_fetch_or(object, operand) \
|
||||||
|
__atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_fetch_or_explicit __atomic_fetch_or
|
||||||
|
|
||||||
|
#define atomic_fetch_xor(object, operand) \
|
||||||
|
__atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_fetch_xor_explicit __atomic_fetch_xor
|
||||||
|
|
||||||
|
#define atomic_fetch_and(object, operand) \
|
||||||
|
__atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_fetch_and_explicit __atomic_fetch_and
|
||||||
|
|
||||||
|
extern void atomic_thread_fence (memory_order);
|
||||||
|
extern void __atomic_thread_fence (memory_order);
|
||||||
|
#define atomic_thread_fence(order) __atomic_thread_fence (order)
|
||||||
|
extern void atomic_signal_fence (memory_order);
|
||||||
|
extern void __atomic_signal_fence (memory_order);
|
||||||
|
#define atomic_signal_fence(order) __atomic_signal_fence (order)
|
||||||
|
extern bool __atomic_is_lock_free(size_t size, void *ptr);
|
||||||
|
#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
|
||||||
|
|
||||||
|
extern bool __atomic_test_and_set (void *, memory_order);
|
||||||
|
extern void __atomic_clear (bool *, memory_order);
|
||||||
|
|
||||||
|
#endif /* _STDATOMIC_H */
|
11
lib/tcc/include/stdbool.h
Normal file
11
lib/tcc/include/stdbool.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _STDBOOL_H
|
||||||
|
#define _STDBOOL_H
|
||||||
|
|
||||||
|
/* ISOC99 boolean */
|
||||||
|
|
||||||
|
#define bool _Bool
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#define __bool_true_false_are_defined 1
|
||||||
|
|
||||||
|
#endif /* _STDBOOL_H */
|
41
lib/tcc/include/stddef.h
Normal file
41
lib/tcc/include/stddef.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef _STDDEF_H
|
||||||
|
#define _STDDEF_H
|
||||||
|
|
||||||
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
typedef __PTRDIFF_TYPE__ ssize_t;
|
||||||
|
typedef __WCHAR_TYPE__ wchar_t;
|
||||||
|
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||||
|
typedef __PTRDIFF_TYPE__ intptr_t;
|
||||||
|
typedef __SIZE_TYPE__ uintptr_t;
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ >= 201112L
|
||||||
|
typedef union { long long __ll; long double __ld; } max_align_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef offsetof
|
||||||
|
#define offsetof(type, field) ((size_t)&((type *)0)->field)
|
||||||
|
|
||||||
|
#if defined __i386__ || defined __x86_64__
|
||||||
|
void *alloca(size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Older glibc require a wint_t from <stddef.h> (when requested
|
||||||
|
by __need_wint_t, as otherwise stddef.h isn't allowed to
|
||||||
|
define this type). Note that this must be outside the normal
|
||||||
|
_STDDEF_H guard, so that it works even when we've included the file
|
||||||
|
already (without requiring wint_t). Some other libs define _WINT_T
|
||||||
|
if they've already provided that type, so we can use that as guard.
|
||||||
|
TCC defines __WINT_TYPE__ for us. */
|
||||||
|
#if defined (__need_wint_t)
|
||||||
|
#ifndef _WINT_T
|
||||||
|
#define _WINT_T
|
||||||
|
typedef __WINT_TYPE__ wint_t;
|
||||||
|
#endif
|
||||||
|
#undef __need_wint_t
|
||||||
|
#endif
|
7
lib/tcc/include/stdnoreturn.h
Normal file
7
lib/tcc/include/stdnoreturn.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef _STDNORETURN_H
|
||||||
|
#define _STDNORETURN_H
|
||||||
|
|
||||||
|
/* ISOC11 noreturn */
|
||||||
|
#define noreturn _Noreturn
|
||||||
|
|
||||||
|
#endif /* _STDNORETURN_H */
|
333
lib/tcc/include/tccdefs.h
Normal file
333
lib/tcc/include/tccdefs.h
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
/* tccdefs.h
|
||||||
|
|
||||||
|
Nothing is defined before this file except target machine, target os
|
||||||
|
and the few things related to option settings in tccpp.c:tcc_predefs().
|
||||||
|
|
||||||
|
This file is either included at runtime as is, or converted and
|
||||||
|
included as C-strings at compile-time (depending on CONFIG_TCC_PREDEFS).
|
||||||
|
|
||||||
|
Note that line indent matters:
|
||||||
|
|
||||||
|
- in lines starting at column 1, platform macros are replaced by
|
||||||
|
corresponding TCC target compile-time macros. See conftest.c for
|
||||||
|
the list of platform macros supported in lines starting at column 1.
|
||||||
|
|
||||||
|
- only lines indented >= 4 are actually included into the executable,
|
||||||
|
check tccdefs_.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if __SIZEOF_POINTER__ == 4
|
||||||
|
/* 32bit systems. */
|
||||||
|
#if defined __OpenBSD__
|
||||||
|
#define __SIZE_TYPE__ unsigned long
|
||||||
|
#define __PTRDIFF_TYPE__ long
|
||||||
|
#else
|
||||||
|
#define __SIZE_TYPE__ unsigned int
|
||||||
|
#define __PTRDIFF_TYPE__ int
|
||||||
|
#endif
|
||||||
|
#define __ILP32__ 1
|
||||||
|
#define __INT64_TYPE__ long long
|
||||||
|
#elif __SIZEOF_LONG__ == 4
|
||||||
|
/* 64bit Windows. */
|
||||||
|
#define __SIZE_TYPE__ unsigned long long
|
||||||
|
#define __PTRDIFF_TYPE__ long long
|
||||||
|
#define __LLP64__ 1
|
||||||
|
#define __INT64_TYPE__ long long
|
||||||
|
#else
|
||||||
|
/* Other 64bit systems. */
|
||||||
|
#define __SIZE_TYPE__ unsigned long
|
||||||
|
#define __PTRDIFF_TYPE__ long
|
||||||
|
#define __LP64__ 1
|
||||||
|
# if defined __linux__
|
||||||
|
#define __INT64_TYPE__ long
|
||||||
|
# else /* APPLE, BSD */
|
||||||
|
#define __INT64_TYPE__ long long
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#define __SIZEOF_INT__ 4
|
||||||
|
#define __INT_MAX__ 0x7fffffff
|
||||||
|
#if __SIZEOF_LONG__ == 4
|
||||||
|
#define __LONG_MAX__ 0x7fffffffL
|
||||||
|
#else
|
||||||
|
#define __LONG_MAX__ 0x7fffffffffffffffL
|
||||||
|
#endif
|
||||||
|
#define __SIZEOF_LONG_LONG__ 8
|
||||||
|
#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL
|
||||||
|
#define __CHAR_BIT__ 8
|
||||||
|
#define __ORDER_LITTLE_ENDIAN__ 1234
|
||||||
|
#define __ORDER_BIG_ENDIAN__ 4321
|
||||||
|
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
|
||||||
|
#if defined _WIN32
|
||||||
|
#define __WCHAR_TYPE__ unsigned short
|
||||||
|
#define __WINT_TYPE__ unsigned short
|
||||||
|
#elif defined __linux__
|
||||||
|
#define __WCHAR_TYPE__ int
|
||||||
|
#define __WINT_TYPE__ unsigned int
|
||||||
|
#else
|
||||||
|
#define __WCHAR_TYPE__ int
|
||||||
|
#define __WINT_TYPE__ int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ >= 201112L
|
||||||
|
# define __STDC_NO_ATOMICS__ 1
|
||||||
|
# define __STDC_NO_COMPLEX__ 1
|
||||||
|
# define __STDC_NO_THREADS__ 1
|
||||||
|
#if !defined _WIN32
|
||||||
|
# define __STDC_UTF_16__ 1
|
||||||
|
# define __STDC_UTF_32__ 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
#define __declspec(x) __attribute__((x))
|
||||||
|
#define __cdecl
|
||||||
|
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
#define __GNUC__ 9
|
||||||
|
#define __GNUC_MINOR__ 3
|
||||||
|
#define __GNUC_PATCHLEVEL__ 0
|
||||||
|
#define __GNUC_STDC_INLINE__ 1
|
||||||
|
#define __NO_TLS 1
|
||||||
|
#define __RUNETYPE_INTERNAL 1
|
||||||
|
# if __SIZEOF_POINTER__ == 8
|
||||||
|
/* FIXME, __int128_t is used by setjump */
|
||||||
|
#define __int128_t struct { unsigned char _dummy[16] __attribute((aligned(16))); }
|
||||||
|
#define __SIZEOF_SIZE_T__ 8
|
||||||
|
#define __SIZEOF_PTRDIFF_T__ 8
|
||||||
|
#else
|
||||||
|
#define __SIZEOF_SIZE_T__ 4
|
||||||
|
#define __SIZEOF_PTRDIFF_T__ 4
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#elif defined __FreeBSD_kernel__
|
||||||
|
|
||||||
|
#elif defined __NetBSD__
|
||||||
|
#define __GNUC__ 4
|
||||||
|
#define __GNUC_MINOR__ 1
|
||||||
|
#define __GNUC_PATCHLEVEL__ 0
|
||||||
|
#define _Pragma(x)
|
||||||
|
#define __ELF__ 1
|
||||||
|
#if defined __aarch64__
|
||||||
|
#define _LOCORE /* avoids usage of __asm */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined __OpenBSD__
|
||||||
|
#define __GNUC__ 4
|
||||||
|
#define _ANSI_LIBRARY 1
|
||||||
|
|
||||||
|
#elif defined __APPLE__
|
||||||
|
/* emulate APPLE-GCC to make libc's headerfiles compile: */
|
||||||
|
#define __GNUC__ 4 /* darwin emits warning on GCC<4 */
|
||||||
|
#define __APPLE_CC__ 1 /* for <TargetConditionals.h> */
|
||||||
|
#define __LITTLE_ENDIAN__ 1
|
||||||
|
#define _DONT_USE_CTYPE_INLINE_ 1
|
||||||
|
/* avoids usage of GCC/clang specific builtins in libc-headerfiles: */
|
||||||
|
#define __FINITE_MATH_ONLY__ 1
|
||||||
|
#define _FORTIFY_SOURCE 0
|
||||||
|
//#define __has_builtin(x) 0
|
||||||
|
|
||||||
|
#elif defined __ANDROID__
|
||||||
|
#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Linux */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some derived integer types needed to get stdint.h to compile correctly on some platforms */
|
||||||
|
#ifndef __NetBSD__
|
||||||
|
#define __UINTPTR_TYPE__ unsigned __PTRDIFF_TYPE__
|
||||||
|
#define __INTPTR_TYPE__ __PTRDIFF_TYPE__
|
||||||
|
#endif
|
||||||
|
#define __INT32_TYPE__ int
|
||||||
|
|
||||||
|
#if !defined _WIN32
|
||||||
|
/* glibc defines. We do not support __USER_NAME_PREFIX__ */
|
||||||
|
#define __REDIRECT(name, proto, alias) name proto __asm__ (#alias)
|
||||||
|
#define __REDIRECT_NTH(name, proto, alias) name proto __asm__ (#alias) __THROW
|
||||||
|
#define __REDIRECT_NTHNL(name, proto, alias) name proto __asm__ (#alias) __THROWNL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* not implemented */
|
||||||
|
#define __PRETTY_FUNCTION__ __FUNCTION__
|
||||||
|
#define __has_builtin(x) 0
|
||||||
|
#define __has_feature(x) 0
|
||||||
|
/* C23 Keywords */
|
||||||
|
#define _Nonnull
|
||||||
|
#define _Nullable
|
||||||
|
#define _Nullable_result
|
||||||
|
#define _Null_unspecified
|
||||||
|
|
||||||
|
/* skip __builtin... with -E */
|
||||||
|
#ifndef __TCC_PP__
|
||||||
|
|
||||||
|
#define __builtin_offsetof(type, field) ((__SIZE_TYPE__)&((type*)0)->field)
|
||||||
|
#define __builtin_extract_return_addr(x) x
|
||||||
|
#if !defined __linux__ && !defined _WIN32
|
||||||
|
/* used by math.h */
|
||||||
|
#define __builtin_huge_val() 1e500
|
||||||
|
#define __builtin_huge_valf() 1e50f
|
||||||
|
#define __builtin_huge_vall() 1e5000L
|
||||||
|
# if defined __APPLE__
|
||||||
|
#define __builtin_nanf(ignored_string) (0.0F/0.0F)
|
||||||
|
/* used by floats.h to implement FLT_ROUNDS C99 macro. 1 == to nearest */
|
||||||
|
#define __builtin_flt_rounds() 1
|
||||||
|
/* used by _fd_def.h */
|
||||||
|
#define __builtin_bzero(p, ignored_size) bzero(p, sizeof(*(p)))
|
||||||
|
# else
|
||||||
|
#define __builtin_nanf(ignored_string) (0.0F/0.0F)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __builtin_va_list */
|
||||||
|
#if defined __x86_64__
|
||||||
|
#if !defined _WIN32
|
||||||
|
/* GCC compatible definition of va_list. */
|
||||||
|
/* This should be in sync with the declaration in our lib/libtcc1.c */
|
||||||
|
typedef struct {
|
||||||
|
unsigned gp_offset, fp_offset;
|
||||||
|
union {
|
||||||
|
unsigned overflow_offset;
|
||||||
|
char *overflow_arg_area;
|
||||||
|
};
|
||||||
|
char *reg_save_area;
|
||||||
|
} __builtin_va_list[1];
|
||||||
|
|
||||||
|
void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align);
|
||||||
|
#define __builtin_va_start(ap, last) \
|
||||||
|
(*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24))
|
||||||
|
#define __builtin_va_arg(ap, t) \
|
||||||
|
(*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t))))
|
||||||
|
#define __builtin_va_copy(dest, src) (*(dest) = *(src))
|
||||||
|
|
||||||
|
#else /* _WIN64 */
|
||||||
|
typedef char *__builtin_va_list;
|
||||||
|
#define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
|
||||||
|
? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined __arm__
|
||||||
|
typedef char *__builtin_va_list;
|
||||||
|
#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
|
||||||
|
#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
|
||||||
|
& ~(_tcc_alignof(type) - 1))
|
||||||
|
#define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
|
||||||
|
#define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
|
||||||
|
&~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
|
||||||
|
|
||||||
|
#elif defined __aarch64__
|
||||||
|
#if defined __APPLE__
|
||||||
|
typedef struct {
|
||||||
|
void *__stack;
|
||||||
|
} __builtin_va_list;
|
||||||
|
|
||||||
|
#else
|
||||||
|
typedef struct {
|
||||||
|
void *__stack, *__gr_top, *__vr_top;
|
||||||
|
int __gr_offs, __vr_offs;
|
||||||
|
} __builtin_va_list;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#elif defined __riscv
|
||||||
|
typedef char *__builtin_va_list;
|
||||||
|
#define __va_reg_size (__riscv_xlen >> 3)
|
||||||
|
#define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \
|
||||||
|
& -(__alignof__(type)))
|
||||||
|
#define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size)))))
|
||||||
|
|
||||||
|
#else /* __i386__ */
|
||||||
|
typedef char *__builtin_va_list;
|
||||||
|
#define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
|
||||||
|
#define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#define __builtin_va_end(ap) (void)(ap)
|
||||||
|
#ifndef __builtin_va_copy
|
||||||
|
# define __builtin_va_copy(dest, src) (dest) = (src)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TCC BBUILTIN AND BOUNDS ALIASES */
|
||||||
|
#ifdef __leading_underscore
|
||||||
|
# define __RENAME(X) __asm__("_"X)
|
||||||
|
#else
|
||||||
|
# define __RENAME(X) __asm__(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __TCC_BCHECK__
|
||||||
|
# define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME("__bound_"#name);
|
||||||
|
# define __BOUND(ret,name,params) ret name params __RENAME("__bound_"#name);
|
||||||
|
#else
|
||||||
|
# define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME(#name);
|
||||||
|
# define __BOUND(ret,name,params)
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define __BOTH __BOUND
|
||||||
|
#define __BUILTIN(ret,name,params)
|
||||||
|
#else
|
||||||
|
#define __BOTH(ret,name,params) __BUILTINBC(ret,name,params)__BOUND(ret,name,params)
|
||||||
|
#define __BUILTIN(ret,name,params) ret __builtin_##name params __RENAME(#name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__))
|
||||||
|
__BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__))
|
||||||
|
__BOTH(void*, memset, (void *, int, __SIZE_TYPE__))
|
||||||
|
__BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__))
|
||||||
|
__BOTH(__SIZE_TYPE__, strlen, (const char *))
|
||||||
|
__BOTH(char*, strcpy, (char *, const char *))
|
||||||
|
__BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__))
|
||||||
|
__BOTH(int, strcmp, (const char*, const char*))
|
||||||
|
__BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__))
|
||||||
|
__BOTH(char*, strcat, (char*, const char*))
|
||||||
|
__BOTH(char*, strncat, (char*, const char*, __SIZE_TYPE__))
|
||||||
|
__BOTH(char*, strchr, (const char*, int))
|
||||||
|
__BOTH(char*, strrchr, (const char*, int))
|
||||||
|
__BOTH(char*, strdup, (const char*))
|
||||||
|
#if defined __ARM_EABI__
|
||||||
|
__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))
|
||||||
|
__BOUND(void*,__aeabi_memmove,(void*,const void*,__SIZE_TYPE__))
|
||||||
|
__BOUND(void*,__aeabi_memmove4,(void*,const void*,__SIZE_TYPE__))
|
||||||
|
__BOUND(void*,__aeabi_memmove8,(void*,const void*,__SIZE_TYPE__))
|
||||||
|
__BOUND(void*,__aeabi_memset,(void*,int,__SIZE_TYPE__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __linux__ || defined __APPLE__ // HAVE MALLOC_REDIR
|
||||||
|
#define __MAYBE_REDIR __BUILTIN
|
||||||
|
#else
|
||||||
|
#define __MAYBE_REDIR __BOTH
|
||||||
|
#endif
|
||||||
|
__MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__))
|
||||||
|
__MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__))
|
||||||
|
__MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))
|
||||||
|
__MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))
|
||||||
|
__MAYBE_REDIR(void, free, (void*))
|
||||||
|
#if defined __i386__ || defined __x86_64__
|
||||||
|
__BOTH(void*, alloca, (__SIZE_TYPE__))
|
||||||
|
#else
|
||||||
|
__BUILTIN(void*, alloca, (__SIZE_TYPE__))
|
||||||
|
#endif
|
||||||
|
__BUILTIN(void, abort, (void))
|
||||||
|
__BOUND(void, longjmp, ())
|
||||||
|
#if !defined _WIN32
|
||||||
|
__BOUND(void*, mmap, ())
|
||||||
|
__BOUND(int, munmap, ())
|
||||||
|
#endif
|
||||||
|
#undef __BUILTINBC
|
||||||
|
#undef __BUILTIN
|
||||||
|
#undef __BOUND
|
||||||
|
#undef __BOTH
|
||||||
|
#undef __MAYBE_REDIR
|
||||||
|
#undef __RENAME
|
||||||
|
|
||||||
|
#define __BUILTIN_EXTERN(name,u) \
|
||||||
|
int __builtin_##name(u int); \
|
||||||
|
int __builtin_##name##l(u long); \
|
||||||
|
int __builtin_##name##ll(u long long);
|
||||||
|
__BUILTIN_EXTERN(ffs,)
|
||||||
|
__BUILTIN_EXTERN(clz, unsigned)
|
||||||
|
__BUILTIN_EXTERN(ctz, unsigned)
|
||||||
|
__BUILTIN_EXTERN(clrsb,)
|
||||||
|
__BUILTIN_EXTERN(popcount, unsigned)
|
||||||
|
__BUILTIN_EXTERN(parity, unsigned)
|
||||||
|
#undef __BUILTIN_EXTERN
|
||||||
|
|
||||||
|
#endif /* ndef __TCC_PP__ */
|
80
lib/tcc/include/tcclib.h
Normal file
80
lib/tcc/include/tcclib.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/* Simple libc header for TCC
|
||||||
|
*
|
||||||
|
* Add any function you want from the libc there. This file is here
|
||||||
|
* only for your convenience so that you do not need to put the whole
|
||||||
|
* glibc include files on your floppy disk
|
||||||
|
*/
|
||||||
|
#ifndef _TCCLIB_H
|
||||||
|
#define _TCCLIB_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* stdlib.h */
|
||||||
|
void *calloc(size_t nmemb, size_t size);
|
||||||
|
void *malloc(size_t size);
|
||||||
|
void free(void *ptr);
|
||||||
|
void *realloc(void *ptr, size_t size);
|
||||||
|
int atoi(const char *nptr);
|
||||||
|
long int strtol(const char *nptr, char **endptr, int base);
|
||||||
|
unsigned long int strtoul(const char *nptr, char **endptr, int base);
|
||||||
|
void exit(int);
|
||||||
|
|
||||||
|
/* stdio.h */
|
||||||
|
typedef struct __FILE FILE;
|
||||||
|
#define EOF (-1)
|
||||||
|
extern FILE *stdin;
|
||||||
|
extern FILE *stdout;
|
||||||
|
extern FILE *stderr;
|
||||||
|
FILE *fopen(const char *path, const char *mode);
|
||||||
|
FILE *fdopen(int fildes, const char *mode);
|
||||||
|
FILE *freopen(const char *path, const char *mode, FILE *stream);
|
||||||
|
int fclose(FILE *stream);
|
||||||
|
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
|
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
|
int fgetc(FILE *stream);
|
||||||
|
char *fgets(char *s, int size, FILE *stream);
|
||||||
|
int getc(FILE *stream);
|
||||||
|
int getchar(void);
|
||||||
|
char *gets(char *s);
|
||||||
|
int ungetc(int c, FILE *stream);
|
||||||
|
int fflush(FILE *stream);
|
||||||
|
int putchar (int c);
|
||||||
|
|
||||||
|
int printf(const char *format, ...);
|
||||||
|
int fprintf(FILE *stream, const char *format, ...);
|
||||||
|
int sprintf(char *str, const char *format, ...);
|
||||||
|
int snprintf(char *str, size_t size, const char *format, ...);
|
||||||
|
int asprintf(char **strp, const char *format, ...);
|
||||||
|
int dprintf(int fd, const char *format, ...);
|
||||||
|
int vprintf(const char *format, va_list ap);
|
||||||
|
int vfprintf(FILE *stream, const char *format, va_list ap);
|
||||||
|
int vsprintf(char *str, const char *format, va_list ap);
|
||||||
|
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||||
|
int vasprintf(char **strp, const char *format, va_list ap);
|
||||||
|
int vdprintf(int fd, const char *format, va_list ap);
|
||||||
|
|
||||||
|
void perror(const char *s);
|
||||||
|
|
||||||
|
/* string.h */
|
||||||
|
char *strcat(char *dest, const char *src);
|
||||||
|
char *strchr(const char *s, int c);
|
||||||
|
char *strrchr(const char *s, int c);
|
||||||
|
char *strcpy(char *dest, const char *src);
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
void *memmove(void *dest, const void *src, size_t n);
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
char *strdup(const char *s);
|
||||||
|
size_t strlen(const char *s);
|
||||||
|
|
||||||
|
/* dlfcn.h */
|
||||||
|
#define RTLD_LAZY 0x001
|
||||||
|
#define RTLD_NOW 0x002
|
||||||
|
#define RTLD_GLOBAL 0x100
|
||||||
|
|
||||||
|
void *dlopen(const char *filename, int flag);
|
||||||
|
const char *dlerror(void);
|
||||||
|
void *dlsym(void *handle, char *symbol);
|
||||||
|
int dlclose(void *handle);
|
||||||
|
|
||||||
|
#endif /* _TCCLIB_H */
|
89
lib/tcc/include/tgmath.h
Normal file
89
lib/tcc/include/tgmath.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* ISO C Standard: 7.22 Type-generic math <tgmath.h>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TGMATH_H
|
||||||
|
#define _TGMATH_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define __tgmath_real(x, F) \
|
||||||
|
_Generic ((x), float: F##f, long double: F##l, default: F)(x)
|
||||||
|
#define __tgmath_real_2_1(x, y, F) \
|
||||||
|
_Generic ((x), float: F##f, long double: F##l, default: F)(x, y)
|
||||||
|
#define __tgmath_real_2(x, y, F) \
|
||||||
|
_Generic ((x)+(y), float: F##f, long double: F##l, default: F)(x, y)
|
||||||
|
#define __tgmath_real_3_2(x, y, z, F) \
|
||||||
|
_Generic ((x)+(y), float: F##f, long double: F##l, default: F)(x, y, z)
|
||||||
|
#define __tgmath_real_3(x, y, z, F) \
|
||||||
|
_Generic ((x)+(y)+(z), float: F##f, long double: F##l, default: F)(x, y, z)
|
||||||
|
|
||||||
|
/* Functions defined in both <math.h> and <complex.h> (7.22p4) */
|
||||||
|
#define acos(z) __tgmath_real(z, acos)
|
||||||
|
#define asin(z) __tgmath_real(z, asin)
|
||||||
|
#define atan(z) __tgmath_real(z, atan)
|
||||||
|
#define acosh(z) __tgmath_real(z, acosh)
|
||||||
|
#define asinh(z) __tgmath_real(z, asinh)
|
||||||
|
#define atanh(z) __tgmath_real(z, atanh)
|
||||||
|
#define cos(z) __tgmath_real(z, cos)
|
||||||
|
#define sin(z) __tgmath_real(z, sin)
|
||||||
|
#define tan(z) __tgmath_real(z, tan)
|
||||||
|
#define cosh(z) __tgmath_real(z, cosh)
|
||||||
|
#define sinh(z) __tgmath_real(z, sinh)
|
||||||
|
#define tanh(z) __tgmath_real(z, tanh)
|
||||||
|
#define exp(z) __tgmath_real(z, exp)
|
||||||
|
#define log(z) __tgmath_real(z, log)
|
||||||
|
#define pow(z1,z2) __tgmath_real_2(z1, z2, pow)
|
||||||
|
#define sqrt(z) __tgmath_real(z, sqrt)
|
||||||
|
#define fabs(z) __tgmath_real(z, fabs)
|
||||||
|
|
||||||
|
/* Functions defined in <math.h> only (7.22p5) */
|
||||||
|
#define atan2(x,y) __tgmath_real_2(x, y, atan2)
|
||||||
|
#define cbrt(x) __tgmath_real(x, cbrt)
|
||||||
|
#define ceil(x) __tgmath_real(x, ceil)
|
||||||
|
#define copysign(x,y) __tgmath_real_2(x, y, copysign)
|
||||||
|
#define erf(x) __tgmath_real(x, erf)
|
||||||
|
#define erfc(x) __tgmath_real(x, erfc)
|
||||||
|
#define exp2(x) __tgmath_real(x, exp2)
|
||||||
|
#define expm1(x) __tgmath_real(x, expm1)
|
||||||
|
#define fdim(x,y) __tgmath_real_2(x, y, fdim)
|
||||||
|
#define floor(x) __tgmath_real(x, floor)
|
||||||
|
#define fma(x,y,z) __tgmath_real_3(x, y, z, fma)
|
||||||
|
#define fmax(x,y) __tgmath_real_2(x, y, fmax)
|
||||||
|
#define fmin(x,y) __tgmath_real_2(x, y, fmin)
|
||||||
|
#define fmod(x,y) __tgmath_real_2(x, y, fmod)
|
||||||
|
#define frexp(x,y) __tgmath_real_2_1(x, y, frexp)
|
||||||
|
#define hypot(x,y) __tgmath_real_2(x, y, hypot)
|
||||||
|
#define ilogb(x) __tgmath_real(x, ilogb)
|
||||||
|
#define ldexp(x,y) __tgmath_real_2_1(x, y, ldexp)
|
||||||
|
#define lgamma(x) __tgmath_real(x, lgamma)
|
||||||
|
#define llrint(x) __tgmath_real(x, llrint)
|
||||||
|
#define llround(x) __tgmath_real(x, llround)
|
||||||
|
#define log10(x) __tgmath_real(x, log10)
|
||||||
|
#define log1p(x) __tgmath_real(x, log1p)
|
||||||
|
#define log2(x) __tgmath_real(x, log2)
|
||||||
|
#define logb(x) __tgmath_real(x, logb)
|
||||||
|
#define lrint(x) __tgmath_real(x, lrint)
|
||||||
|
#define lround(x) __tgmath_real(x, lround)
|
||||||
|
#define nearbyint(x) __tgmath_real(x, nearbyint)
|
||||||
|
#define nextafter(x,y) __tgmath_real_2(x, y, nextafter)
|
||||||
|
#define nexttoward(x,y) __tgmath_real_2(x, y, nexttoward)
|
||||||
|
#define remainder(x,y) __tgmath_real_2(x, y, remainder)
|
||||||
|
#define remquo(x,y,z) __tgmath_real_3_2(x, y, z, remquo)
|
||||||
|
#define rint(x) __tgmath_real(x, rint)
|
||||||
|
#define round(x) __tgmath_real(x, round)
|
||||||
|
#define scalbln(x,y) __tgmath_real_2_1(x, y, scalbln)
|
||||||
|
#define scalbn(x,y) __tgmath_real_2_1(x, y, scalbn)
|
||||||
|
#define tgamma(x) __tgmath_real(x, tgamma)
|
||||||
|
#define trunc(x) __tgmath_real(x, trunc)
|
||||||
|
|
||||||
|
/* Functions defined in <complex.h> only (7.22p6)
|
||||||
|
#define carg(z) __tgmath_cplx_only(z, carg)
|
||||||
|
#define cimag(z) __tgmath_cplx_only(z, cimag)
|
||||||
|
#define conj(z) __tgmath_cplx_only(z, conj)
|
||||||
|
#define cproj(z) __tgmath_cplx_only(z, cproj)
|
||||||
|
#define creal(z) __tgmath_cplx_only(z, creal)
|
||||||
|
*/
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif /* _TGMATH_H */
|
12
lib/tcc/include/varargs.h
Normal file
12
lib/tcc/include/varargs.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* This file has no copyright assigned and is placed in the Public Domain.
|
||||||
|
* This file is part of the w64 mingw-runtime package.
|
||||||
|
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||||
|
*/
|
||||||
|
#ifndef _VARARGS_H
|
||||||
|
#define _VARARGS_H
|
||||||
|
|
||||||
|
#error "TinyCC no longer implements <varargs.h>."
|
||||||
|
#error "Revise your code to use <stdarg.h>."
|
||||||
|
|
||||||
|
#endif
|
BIN
lib/tcc/libtcc1.a
Normal file
BIN
lib/tcc/libtcc1.a
Normal file
Binary file not shown.
26
runtime/runtime.c
Normal file
26
runtime/runtime.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "runtime.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int subtract(int a, int b) {
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int divide(int a, int b) {
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int multiply(int a, int b) {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_str(const char* s) {
|
||||||
|
printf("%s\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_num(int n) {
|
||||||
|
printf("%d\n", n);
|
||||||
|
}
|
12
runtime/runtime.h
Normal file
12
runtime/runtime.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __RUNTIME_H__
|
||||||
|
#define __RUNTIME_H__
|
||||||
|
|
||||||
|
int add(int a, int b);
|
||||||
|
int subtract(int a, int b);
|
||||||
|
int divide(int a, int b);
|
||||||
|
int multiply(int a, int b);
|
||||||
|
|
||||||
|
void print_str(const char* s);
|
||||||
|
void print_num(int n);
|
||||||
|
|
||||||
|
#endif
|
131
src/ast.c
Normal file
131
src/ast.c
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include <ast.h>
|
||||||
|
|
||||||
|
const char* ASTTypeText[] = {
|
||||||
|
"Program",
|
||||||
|
"CallExpression",
|
||||||
|
"NumberLiteral",
|
||||||
|
"StringLiteral"
|
||||||
|
};
|
||||||
|
|
||||||
|
ASTNode* ast_parse(Token** token) {
|
||||||
|
ASTVec body = { 0 };
|
||||||
|
|
||||||
|
while((*token) != NULL) {
|
||||||
|
sl_vec_push(body, ast_walk(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ast_create_program(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_walk(Token** token) {
|
||||||
|
if((*token)->type == TOKEN_NUMBER) {
|
||||||
|
ASTNode* number = ast_create_number_literal((*token)->value);
|
||||||
|
ast_step(token);
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*token)->type == TOKEN_STRING) {
|
||||||
|
ASTNode* string = ast_create_string_literal((*token)->value);
|
||||||
|
ast_step(token);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*token)->type == TOKEN_LPAREN) { // Call expression
|
||||||
|
ast_step(token);
|
||||||
|
const char* name = (*token)->value;
|
||||||
|
ASTVec params = { 0 };
|
||||||
|
|
||||||
|
ast_step(token);
|
||||||
|
|
||||||
|
while((*token)->type != TOKEN_RPAREN) {
|
||||||
|
sl_vec_push(params, ast_walk(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_step(token);
|
||||||
|
|
||||||
|
return ast_create_call_expression(name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_step(Token** token) {
|
||||||
|
(*token) = (*token)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* gen_ident(int indent) {
|
||||||
|
char* text = malloc(sizeof(char) * (indent + 1));
|
||||||
|
memset(text, ' ', indent);
|
||||||
|
text[indent] = '\0';
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_print(ASTNode* node, int indent) {
|
||||||
|
switch(node->type) {
|
||||||
|
case AST_PROGRAM:
|
||||||
|
printf("%s%s\n%sBody:\n",
|
||||||
|
gen_ident(indent), ASTTypeText[node->type],
|
||||||
|
gen_ident(indent + 2));
|
||||||
|
|
||||||
|
indent += 2;
|
||||||
|
for(sl_vec_it(n, node->body)) {
|
||||||
|
ast_print(*n, indent + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_CALL_EXPRESSION:
|
||||||
|
printf("%s%s\n%sName: %s\n%sParams:\n",
|
||||||
|
gen_ident(indent), ASTTypeText[node->type],
|
||||||
|
gen_ident(indent + 2), node->name,
|
||||||
|
gen_ident(indent + 2));
|
||||||
|
|
||||||
|
indent += 2;
|
||||||
|
for(sl_vec_it(n, node->params)) {
|
||||||
|
ast_print(*n, indent + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NUMBER_LITERAL:
|
||||||
|
printf("%s%s\n%sValue: %s\n",
|
||||||
|
gen_ident(indent), ASTTypeText[node->type],
|
||||||
|
gen_ident(indent + 2), node->value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_STRING_LITERAL:
|
||||||
|
printf("%s%s\n%sValue: %s\n",
|
||||||
|
gen_ident(indent), ASTTypeText[node->type],
|
||||||
|
gen_ident(indent + 2), node->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_create_empty(ASTType type) {
|
||||||
|
ASTNode* new_node = malloc(sizeof(ASTNode));
|
||||||
|
new_node->type = type;
|
||||||
|
return new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_create_program(ASTVec body) {
|
||||||
|
ASTNode* node = ast_create_empty(AST_PROGRAM);
|
||||||
|
node->body = body;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_create_call_expression(const char* name, ASTVec params) {
|
||||||
|
ASTNode* node = ast_create_empty(AST_CALL_EXPRESSION);
|
||||||
|
node->name = name;
|
||||||
|
node->params = params;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_create_number_literal(const char* value) {
|
||||||
|
ASTNode* node = ast_create_empty(AST_NUMBER_LITERAL);
|
||||||
|
node->value = value;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* ast_create_string_literal(const char* value) {
|
||||||
|
ASTNode* node = ast_create_empty(AST_STRING_LITERAL);
|
||||||
|
node->value = value;
|
||||||
|
return node;
|
||||||
|
}
|
40
src/codegen.c
Normal file
40
src/codegen.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include <codegen.h>
|
||||||
|
#include <slibs/slibs.h>
|
||||||
|
|
||||||
|
const char* codegen(ASTNode* node) {
|
||||||
|
if(node->type == AST_PROGRAM) {
|
||||||
|
sl_string code = sl_string("#include <runtime.h>\n\nint main() {\n");
|
||||||
|
for(sl_vec_it(n, node->body)) {
|
||||||
|
sl_append_c_str(&code, codegen(*n));
|
||||||
|
sl_append_c_str(&code, ";\n");
|
||||||
|
}
|
||||||
|
sl_append_c_str(&code, "}");
|
||||||
|
return sl_c_str(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node->type == AST_CALL_EXPRESSION) {
|
||||||
|
sl_string code = sl_string(node->name);
|
||||||
|
sl_append_c_str(&code, "(");
|
||||||
|
for(size_t i = 0; i < node->params.size; i++) {
|
||||||
|
sl_append_c_str(&code, codegen(node->params.data[i]));
|
||||||
|
if(i < node->params.size - 1) {
|
||||||
|
sl_append_c_str(&code, ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sl_append_c_str(&code, ")");
|
||||||
|
return sl_c_str(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node->type == AST_NUMBER_LITERAL) {
|
||||||
|
return node->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node->type == AST_STRING_LITERAL) {
|
||||||
|
sl_string code = sl_string("\"");
|
||||||
|
sl_append_c_str(&code, node->value);
|
||||||
|
sl_append_c_str(&code, "\"");
|
||||||
|
return sl_c_str(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
41
src/main.c
Normal file
41
src/main.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#define SL_IMPLEMENTATION
|
||||||
|
#include <slibs/slibs.h>
|
||||||
|
#include <tokenizer.h>
|
||||||
|
#include <ast.h>
|
||||||
|
#include <codegen.h>
|
||||||
|
#include <tcc/libtcc.h>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
assert(argc > 2);
|
||||||
|
|
||||||
|
sl_string buffer = { 0 };
|
||||||
|
sl_read_file(argv[1], &buffer);
|
||||||
|
|
||||||
|
Token* root = tokenize(sl_c_str(buffer));
|
||||||
|
printf("Tokens:\n");
|
||||||
|
Token* curr = root;
|
||||||
|
while(curr != NULL) {
|
||||||
|
printf("%s: %s\n", TokenTypeText[curr->type], curr->value);
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("AST:\n");
|
||||||
|
ASTNode* program = ast_parse(&root);
|
||||||
|
ast_print(program, 0);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Codegen:\n");
|
||||||
|
const char* code = codegen(program);
|
||||||
|
printf("%s\n\n", code);
|
||||||
|
|
||||||
|
TCCState* state = tcc_new();
|
||||||
|
assert(tcc_set_output_type(state, TCC_OUTPUT_EXE) == 0);
|
||||||
|
tcc_set_lib_path(state, "lib/tcc");
|
||||||
|
assert(tcc_add_include_path(state, "runtime") == 0);
|
||||||
|
assert(tcc_add_file(state, "runtime/runtime.c") == 0);
|
||||||
|
assert(tcc_compile_string(state, code) == 0);
|
||||||
|
assert(tcc_output_file(state, argv[2]) == 0);
|
||||||
|
|
||||||
|
printf("Binary produced: %s\n", argv[2]);
|
||||||
|
}
|
69
src/regexp.c
Normal file
69
src/regexp.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <regexp.h>
|
||||||
|
|
||||||
|
void regex_step(char** input, char* c) {
|
||||||
|
(*input)++;
|
||||||
|
*c = **input;
|
||||||
|
}
|
||||||
|
|
||||||
|
regex_t regex_create(const char* pattern, int flags) {
|
||||||
|
regex_t regex;
|
||||||
|
int ret = regcomp(®ex, pattern, flags);
|
||||||
|
if(ret) {
|
||||||
|
char msgbuf[100];
|
||||||
|
regerror(ret, ®ex, msgbuf, sizeof(msgbuf));
|
||||||
|
fprintf(stderr, "Regex compilation failed: %s\n", msgbuf);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int match_char(regex_t regex, char c) {
|
||||||
|
return regnexec(®ex, &c, 1, 0, NULL, 0) != REG_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_string collect_until(match_func matcher, regex_t regex, char** input) {
|
||||||
|
sl_string collected = {0};
|
||||||
|
char c = **input;
|
||||||
|
|
||||||
|
while (matcher(regex, c, input)) {
|
||||||
|
sl_vec_push(collected, c);
|
||||||
|
regex_step(input, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return collected;
|
||||||
|
}
|
||||||
|
|
||||||
|
int not_match_char(regex_t regex, char c, char** _) {
|
||||||
|
return !match_char(regex, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int match_char_matcher(regex_t regex, char c, char** _) {
|
||||||
|
return match_char(regex, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int not_match_char_escapable(regex_t regex, char c, char** input) {
|
||||||
|
return !match_char(regex, c) || *((*input) - 1) == '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
int match_char_escapable(regex_t regex, char c, char** input) {
|
||||||
|
return match_char(regex, c) || *(*input) == '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_string collect_until_match(regex_t regex, char** input) {
|
||||||
|
return collect_until(not_match_char, regex, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_string collect_until_no_match(regex_t regex, char** input) {
|
||||||
|
return collect_until(match_char_matcher, regex, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_string collect_until_match_escapable(regex_t regex, char** input) {
|
||||||
|
return collect_until(not_match_char_escapable, regex, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_string collect_until_no_match_escapable(regex_t regex, char** input) {
|
||||||
|
return collect_until(match_char_escapable, regex, input);
|
||||||
|
}
|
77
src/tokenizer.c
Normal file
77
src/tokenizer.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <regexp.h>
|
||||||
|
#include <tokenizer.h>
|
||||||
|
#include <slibs/slibs.h>
|
||||||
|
|
||||||
|
const char* TokenTypeText[] = {
|
||||||
|
"l_paren",
|
||||||
|
"r_paren",
|
||||||
|
"number",
|
||||||
|
"name",
|
||||||
|
"string"
|
||||||
|
};
|
||||||
|
|
||||||
|
Token* tokenize(char* input) {
|
||||||
|
regex_t name = regex_create("[a-z_]", REG_ICASE);
|
||||||
|
regex_t number = regex_create("[0-9]", 0);
|
||||||
|
regex_t string = regex_create("\"", 0);
|
||||||
|
regex_t whitespace = regex_create("[ \n]", 0);
|
||||||
|
Token* root = NULL;
|
||||||
|
sl_string collected = {0};
|
||||||
|
|
||||||
|
char c = *input;
|
||||||
|
while (c != '\0') {
|
||||||
|
if (match_char(name, c)) {
|
||||||
|
collected = collect_until_no_match(name, &input);
|
||||||
|
root = token_create(sl_c_str(collected), TOKEN_NAME, root);
|
||||||
|
} else if (match_char(number, c)) {
|
||||||
|
collected = collect_until_no_match(number, &input);
|
||||||
|
root = token_create(sl_c_str(collected), TOKEN_NUMBER, root);
|
||||||
|
} else if (c == '(') {
|
||||||
|
root = token_create("(", TOKEN_LPAREN, root);
|
||||||
|
input++;
|
||||||
|
} else if (c == ')') {
|
||||||
|
root = token_create(")", TOKEN_RPAREN, root);
|
||||||
|
input++;
|
||||||
|
} else if (match_char(whitespace, c)) {
|
||||||
|
input++;
|
||||||
|
} else if (match_char(string, c)) {
|
||||||
|
regex_step(&input, &c);
|
||||||
|
collected = collect_until_match_escapable(string, &input);
|
||||||
|
root = token_create(sl_c_str(collected), TOKEN_STRING, root);
|
||||||
|
input++;
|
||||||
|
} else {
|
||||||
|
printf("%c: no match\n", c);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *input;
|
||||||
|
}
|
||||||
|
|
||||||
|
regfree(&name);
|
||||||
|
regfree(&number);
|
||||||
|
regfree(&string);
|
||||||
|
regfree(&whitespace);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* token_create(char* value, TokenType type, Token* root) {
|
||||||
|
Token* new_token = malloc(sizeof(Token));
|
||||||
|
new_token->value = value;
|
||||||
|
new_token->type = type;
|
||||||
|
|
||||||
|
return token_append(root, new_token);;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* token_append(Token* root, Token* new_token) {
|
||||||
|
if (!root) return new_token;
|
||||||
|
Token* current = root;
|
||||||
|
while (current->next) {
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
current->next = new_token;
|
||||||
|
return root;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue