2, support <stdlib.h>, <string.h>, <stddef.h>, <stdarg.h> of musl libc.
{SCF_OP_OR_ASSIGN, "|="},
{SCF_OP_VA_START, "va_start"},
+ {SCF_OP_VA_COPY, "va_copy"},
{SCF_OP_VA_ARG, "va_arg"},
{SCF_OP_VA_END, "va_end"},
return 0;
}
-int scf_function_signature(scf_ast_t* ast, scf_function_t* f)
+int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv)
{
scf_string_t* s;
- scf_type_t* t = (scf_type_t*)f->node.parent;
-
int ret;
int i;
goto error;
}
- if (f->op_type >= 0) {
- scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
-
- if (!op->signature)
- goto error;
-
- ret = scf_string_cat_cstr(s, op->signature);
- } else
- ret = scf_string_cat(s, f->node.w->text);
-
+ ret = scf_string_cat_cstr(s, fname);
if (ret < 0)
goto error;
scf_logd("f signature: %s\n", s->data);
if (t->node.type < SCF_STRUCT) {
- if (f->signature)
- scf_string_free(f->signature);
-
- f->signature = s;
+ *ps = s;
return 0;
}
- if (f->argv) {
- for (i = 0; i < f->argv->size; i++) {
- scf_variable_t* v = f->argv->data[i];
- scf_type_t* t_v = NULL;
+ if (argv) {
+ scf_variable_t* v;
+ scf_type_t* t_v;
+
+ for (i = 0; i < argv->size; i++) {
+ v = argv->data[i];
t_v = scf_block_find_type_type((scf_block_t*)t, v->type);
if (!t_v) {
scf_logd("f signature: %s\n", s->data);
- if (f->signature)
- scf_string_free(f->signature);
- f->signature = s;
+ *ps = s;
return 0;
error:
scf_string_free(s);
- return -1;
+ return ret;
+}
+
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv)
+{
+ char* fname = f->node.w->text->data;
+
+ if (f->op_type >= 0) {
+ scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
+
+ if (!op->signature)
+ return -EINVAL;
+
+ fname = op->signature;
+ }
+
+ if (!argv)
+ argv = f->argv;
+
+ if (f->signature) {
+ scf_string_free(f->signature);
+ f->signature = NULL;
+ }
+
+ return scf_function_signature2(&f->signature, ast, (scf_type_t*)f->node.parent, fname, argv);
}
int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv)
int scf_ast_add_file_block(scf_ast_t* ast, const char* path);
-int scf_function_signature(scf_ast_t* ast, scf_function_t* f);
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv);
+
+int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv);
int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w);
int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64);
{".", "p", SCF_OP_POINTER, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"va_start", NULL, SCF_OP_VA_START, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"va_copy", NULL, SCF_OP_VA_COPY, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"va_arg", NULL, SCF_OP_VA_ARG, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"va_end", NULL, SCF_OP_VA_END, 1, 1, SCF_OP_ASSOCIATIVITY_LEFT},
{"container", NULL, SCF_OP_CONTAINER, 1, 3, SCF_OP_ASSOCIATIVITY_LEFT},
vptr->tmp_flag = 1;
nptr = scf_node_alloc(NULL, vptr->type, vptr);
+
+ scf_variable_free(vptr);
+ vptr = NULL;
if (!nptr)
return -ENOMEM;
- if (scf_node_add_child(parent, nptr) < 0)
+ if (scf_node_add_child(parent, nptr) < 0) {
+ scf_node_free(nptr);
return -ENOMEM;
+ }
srcs[0] = parent->nodes[0];
srcs[1] = parent->nodes[1];
return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_START, srcs, 3);
}
+static int _scf_op_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_handler_data_t* d = data;
+
+ return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_COPY, nodes, nb_nodes);
+}
+
static int _scf_op_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(1 == nb_nodes);
[SCF_OP_POINTER ] = _scf_op_pointer,
[SCF_OP_VA_START] = _scf_op_va_start,
+ [SCF_OP_VA_COPY ] = _scf_op_va_copy,
[SCF_OP_VA_ARG ] = _scf_op_va_arg,
[SCF_OP_VA_END ] = _scf_op_va_end,
#include<stdio.h>
+#include<stdlib.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stddef.h>
int main()
{
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stddef.h>
+
+struct A
+{
+ long x;
+ int y;
+ short z;
+};
+
+int main()
+{
+ printf("offsetof(A, z): %ld\n", offsetof(A, z));
+ return 0;
+}
int scf_printf(const char* fmt, ...)
{
va_list ap;
+ va_list ap2;
char buf[1024];
va_start(ap, fmt);
- int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap);
+ va_copy(ap2, ap);
+
+ int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap2);
+
+ va_end(ap2);
va_end(ap);
if (ret > 0) {
}
/*
-
struct va_list
{
uint8_t* iptr;
return 0;
}
+static int _x64_inst_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+ scf_x64_context_t* x64 = ctx->priv;
+ scf_function_t* f = x64->f;
+
+ if (!c->instructions) {
+ c->instructions = scf_vector_alloc();
+ if (!c->instructions)
+ return -ENOMEM;
+ }
+
+ assert(2 == c->srcs->size);
+
+ scf_instruction_t* inst = NULL;
+ scf_register_t* r0 = NULL;
+ scf_register_t* r1 = NULL;
+ scf_register_t* r = NULL;
+
+ scf_3ac_operand_t* ap0 = c->srcs->data[0];
+ scf_3ac_operand_t* ap1 = c->srcs->data[1];
+ scf_x64_OpCode_t* P2G = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G);
+ scf_x64_OpCode_t* G2P = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
+ scf_variable_t* v0 = ap0->dag_node->var;
+ scf_variable_t* v1 = ap1->dag_node->var;
+
+ if (v0->bp_offset >= 0 || v1->bp_offset >= 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ X64_SELECT_REG_CHECK(&r0, ap0->dag_node, c, f, 1);
+ X64_SELECT_REG_CHECK(&r1, ap1->dag_node, c, f, 1);
+
+ int ret = x64_select_free_reg(&r, c, f, 0);
+ if (ret < 0)
+ return ret;
+
+ // iptr: offset 0
+ inst = x64_make_inst_P2G(P2G, r, r1, 0);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ inst = x64_make_inst_G2P(G2P, r0, 0, r);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ // fptr: offset 8
+ inst = x64_make_inst_P2G(P2G, r, r1, 8);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ inst = x64_make_inst_G2P(G2P, r0, 8, r);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ // optr: offset 16
+ inst = x64_make_inst_P2G(P2G, r, r1, 16);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ inst = x64_make_inst_G2P(G2P, r0, 16, r);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ // ireg: offset 24
+ inst = x64_make_inst_P2G(P2G, r, r1, 24);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ inst = x64_make_inst_G2P(G2P, r0, 24, r);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ // freg: offset 32
+ inst = x64_make_inst_P2G(P2G, r, r1, 32);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+
+ inst = x64_make_inst_G2P(G2P, r0, 32, r);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+ return 0;
+}
+
static int _x64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
scf_x64_context_t* x64 = ctx->priv;
[SCF_OP_NEG ] = _x64_inst_neg_handler,
[SCF_OP_VA_START ] = _x64_inst_va_start_handler,
+ [SCF_OP_VA_COPY ] = _x64_inst_va_copy_handler,
[SCF_OP_VA_ARG ] = _x64_inst_va_arg_handler,
[SCF_OP_VA_END ] = _x64_inst_va_end_handler,
return x64_rcg_make(c, g, NULL, NULL);
}
+static int _x64_rcg_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
+{
+ int ret = x64_rcg_make2(c, NULL, NULL);
+ if (ret < 0)
+ return ret;
+ return x64_rcg_make(c, g, NULL, NULL);
+}
+
static int _x64_rcg_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
int ret = x64_rcg_make2(c, NULL, NULL);
[SCF_OP_NEG ] = _x64_rcg_neg_handler,
[SCF_OP_VA_START ] = _x64_rcg_va_start_handler,
+ [SCF_OP_VA_COPY ] = _x64_rcg_va_copy_handler,
[SCF_OP_VA_ARG ] = _x64_rcg_va_arg_handler,
[SCF_OP_VA_END ] = _x64_rcg_va_end_handler,
scf_stack_t* ls_exprs;
scf_stack_t* lp_exprs;
scf_block_t* parent_block;
- scf_variable_t* current_var;
+
scf_type_t* current_struct;
} expr_module_data_t;
scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
node = scf_node_alloc(w, var->type, var);
+
+ scf_variable_free(var);
+ var = NULL;
if (!node)
return -ENOMEM;
return SCF_DFA_ERROR;
}
- if (var->type >= SCF_STRUCT) {
+ if (node->var->type >= SCF_STRUCT) {
- int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, var->type);
+ int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type);
if (ret < 0)
return SCF_DFA_ERROR;
+
assert(md->current_struct);
}
- md->current_var = var;
free(id);
id = NULL;
return SCF_DFA_ERROR;
}
- if (scf_function_signature(parse->ast, f) < 0)
+ if (scf_function_signature(parse->ast, f, NULL) < 0)
return SCF_DFA_ERROR;
w->text->data[2] = '\0';
}
scf_variable_t* var = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, nb_pointers, NULL);
- if (!var) {
- scf_loge("var '%s' alloc failed\n", w->text->data);
- return SCF_DFA_ERROR;
- }
+ if (!var)
+ return -ENOMEM;
- scf_node_t* n = scf_node_alloc(w, var->type, var);
- if (!n) {
- scf_loge("var node '%s' alloc failed\n", w->text->data);
- return SCF_DFA_ERROR;
- }
+ scf_node_t* node = scf_node_alloc(w, var->type, var);
- if (scf_expr_add_node(d->expr, n) < 0) {
- scf_loge("add var node '%s' to expr failed\n", w->text->data);
+ scf_variable_free(var);
+ var = NULL;
+ if (!node)
+ return -ENOMEM;
+
+ if (scf_expr_add_node(d->expr, node) < 0) {
+ scf_node_free(node);
return SCF_DFA_ERROR;
}
if (d->current_va_arg || d->current_va_copy)
return SCF_DFA_NEXT_SYNTAX;
- scf_variable_t* var = NULL;
- scf_node_t* node_var = NULL;
- scf_node_t* node_cast = NULL;
+ scf_variable_t* var = NULL;
+ scf_node_t* node = NULL;
+ scf_node_t* cast = NULL;
+ scf_expr_t* e = NULL;
var = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, id->func_ptr);
- if (!var) {
- scf_loge("var alloc failed\n");
+ if (!var)
return SCF_DFA_ERROR;
- }
- node_var = scf_node_alloc(NULL, var->type, var);
- if (!node_var) {
- scf_loge("var node alloc failed\n");
+ node = scf_node_alloc(NULL, var->type, var);
+
+ scf_variable_free(var);
+ var = NULL;
+ if (!node)
return SCF_DFA_ERROR;
- }
- node_cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL);
- if (!node_cast) {
- scf_loge("cast node alloc failed\n");
+ cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL);
+ if (!cast) {
+ scf_node_free(node);
return SCF_DFA_ERROR;
}
- scf_node_add_child(node_cast, node_var);
- // '(' lp action pushed a expr before
- scf_expr_t* e = scf_stack_pop(md->lp_exprs);
-
- scf_logd("type cast: d->expr: %p, d->expr->parent: %p, e: %p\n", d->expr, d->expr->parent, e);
+ int ret = scf_node_add_child(cast, node);
+ if (ret < 0) {
+ scf_node_free(cast);
+ scf_node_free(node);
+ return ret;
+ }
+ // '(' lp action pushed a expr before
+ e = scf_stack_pop(md->lp_exprs);
assert(e);
- scf_expr_add_node(e, node_cast);
+ ret = scf_expr_add_node(e, cast);
+ if (ret < 0) {
+ scf_node_free(cast);
+ scf_expr_free(e);
+ return ret;
+ }
+
d->expr = e;
+ e = NULL;
+
+ if (node->var->type >= SCF_STRUCT) {
+
+ ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type);
+ if (ret < 0)
+ return SCF_DFA_ERROR;
+
+ assert(md->current_struct);
+ }
scf_stack_pop(d->current_identities);
free(id);
scf_dfa_node_add_child(rs, binary_op);
scf_dfa_node_add_child(rs, unary_post);
scf_dfa_node_add_child(rs, rp);
+ scf_dfa_node_add_child(rp, ls);
scf_dfa_node_add_child(identity, unary_post);
scf_dfa_node_add_child(identity, rs);
int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
-int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
+
+int _function_add_rets(scf_function_t* f, dfa_data_t* d)
+{
+ dfa_identity_t* id;
+ scf_variable_t* v;
+
+ int void_flag = 0;
+
+ while (d->current_identities->size > 0) {
+
+ id = scf_stack_pop(d->current_identities);
+ if (!id)
+ return SCF_DFA_ERROR;
+
+ if (!id->type) {
+ assert(id->identity);
+
+ scf_loge("%s:%d:%d, function return value type '%s' NOT found\n",
+ id->identity->file->data, id->identity->line, id->identity->pos,
+ id->identity->text->data);
+ return SCF_DFA_ERROR;
+ }
+
+ if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers)
+ void_flag = 1;
+
+ f->extern_flag |= id->extern_flag;
+ f->static_flag |= id->static_flag;
+ f->inline_flag |= id->inline_flag;
+
+ if (f->extern_flag && (f->static_flag || f->inline_flag)) {
+ scf_loge("'extern' function can't be 'static' or 'inline'\n");
+ return SCF_DFA_ERROR;
+ }
+
+ v = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL);
+ free(id);
+ id = NULL;
+
+ if (!v)
+ return SCF_DFA_ERROR;
+
+ if (scf_vector_add(f->rets, v) < 0) {
+ scf_variable_free(v);
+ return SCF_DFA_ERROR;
+ }
+ }
+
+ assert(f->rets->size > 0);
+
+ if (void_flag && 1 != f->rets->size) {
+ scf_loge("void function must have no other return value\n");
+ return SCF_DFA_ERROR;
+ }
+
+ f->void_flag = void_flag;
+
+ if (f->rets->size > 4) {
+ scf_loge("function return values must NOT more than 4!\n");
+ return SCF_DFA_ERROR;
+ }
+
+ int i;
+ int j;
+ for (i = 0; i < f->rets->size / 2; i++) {
+ j = f->rets->size - 1 - i;
+
+ SCF_XCHG(f->rets->data[i], f->rets->data[j]);
+ }
+
+ return 0;
+}
+
+int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d, scf_lex_word_t* lp)
{
scf_parse_t* parse = dfa->priv;
scf_ast_t* ast = parse->ast;
return -ENOMEM;
} else {
- id = scf_stack_pop(d->current_identities);
-
- if (!id || !id->identity) {
- scf_loge("function identity not found\n");
+ id = scf_stack_top(d->current_identities);
+ if (!id) {
+ scf_loge("%s:%d:%d, lost 'void' when declare function pointer\n", lp->file->data, lp->line, lp->pos);
return SCF_DFA_ERROR;
}
- name = id->identity;
+ if (id->identity)
+ name = id->identity;
+ else
+ name = id->type_w;
}
uint32_t local_flag = 0;
v_pf = d->current_var;
assert(d->current_identities->size > 0);
- id0 = d->current_identities->data[0];
+ id0 = d->current_identities->data[0];
if (id0->typedef_flag) {
id0->typedef_flag = 0;
return SCF_DFA_ERROR;
f->member_flag = member_flag;
- if (id) {
+ if (id && d->current_identities->size > 1) {
+ scf_stack_pop(d->current_identities);
free(id);
- id = NULL;
}
+ id = NULL;
scf_logi("s->size: %d, function: %s(), line: %d, member_flag: %d\n", s->size, f->node.w->text->data, f->node.w->line, f->member_flag);
- int void_flag = 0;
-
- while (d->current_identities->size > 0) {
-
- id = scf_stack_pop(d->current_identities);
-
- if (!id || !id->type || !id->type_w) {
- scf_loge("function return value type NOT found\n");
- return SCF_DFA_ERROR;
- }
-
- if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers)
- void_flag = 1;
-
- f->extern_flag |= id->extern_flag;
- f->static_flag |= id->static_flag;
- f->inline_flag |= id->inline_flag;
-
- if (f->extern_flag && (f->static_flag || f->inline_flag)) {
- scf_loge("'extern' function can't be 'static' or 'inline'\n");
- return SCF_DFA_ERROR;
- }
-
- v = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL);
- free(id);
- id = NULL;
-
- if (!v) {
- scf_function_free(f);
- return SCF_DFA_ERROR;
- }
-
- if (scf_vector_add(f->rets, v) < 0) {
- scf_variable_free(v);
- scf_function_free(f);
- return SCF_DFA_ERROR;
- }
- }
-
- assert(f->rets->size > 0);
-
- if (void_flag && 1 != f->rets->size) {
- scf_loge("void function must have no other return value\n");
- return SCF_DFA_ERROR;
- }
-
- f->void_flag = void_flag;
-
- if (f->rets->size > 4) {
- scf_loge("function return values must NOT more than 4!\n");
- return SCF_DFA_ERROR;
- }
-
- int i;
- int j;
- for (i = 0; i < f->rets->size / 2; i++) {
- j = f->rets->size - 1 - i;
-
- SCF_XCHG(f->rets->data[i], f->rets->data[j]);
+ int ret = _function_add_rets(f, d);
+ if (ret < 0) {
+ scf_function_free(f);
+ return ret;
}
if (v_pf) {
arg->dimentions = NULL;
}
- arg->const_literal_flag = 0;
-
scf_logi("s->size: %d, fd->f: %s(), fd->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
s->size, fd->f->node.w->text->data, fd->argc, arg->nb_pointers, arg->nb_dimentions);
+ arg->const_literal_flag = 0;
+
assert(scf_vector_find(fd->f->scope->vars, arg));
scf_vector_add(fd->f->argv, arg);
static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_parse_t* parse = dfa->priv;
+ scf_lex_word_t* w = words->data[words->size - 1];
dfa_data_t* d = data;
scf_stack_t* s = d->module_datas[dfa_module_function.index];
dfa_fun_data_t* fd = calloc(1, sizeof(dfa_fun_data_t));
if (d->pf_pointers <= 0)
d->current_var = NULL;
- ret = _function_add_function(dfa, d);
+ ret = _function_add_function(dfa, d, w);
if (ret < 0)
return ret;
d->current_var = NULL;
+ d->arg_flag = 1;
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"), SCF_DFA_HOOK_PRE);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_comma"), SCF_DFA_HOOK_PRE);
scf_logi("f: %s(), fd->nb_lps: %d, fd->nb_rps: %d\n", f->node.w->text->data, fd->nb_lps, fd->nb_rps);
+ d->arg_flag = 0;
+
if (_function_add_arg(dfa, d) < 0)
return SCF_DFA_ERROR;
scf_dfa_node_add_child(identity, assign);
scf_dfa_node_add_child(rs, pf_rp);
+ scf_dfa_node_add_child(pf_star, pf_rp);
scf_dfa_node_add_child(pf_star, pf_star);
scf_dfa_node_add_child(pf_lp, pf_lp);
scf_dfa_node_add_child(pf_rp, pf_rp);
extern scf_dfa_module_t dfa_module_identity;
+static scf_key_word_t future_key_words[] =
+{
+ {SCF_CSTR("_Noreturn"), -1},
+};
+
+void warning_future_key_word(scf_lex_word_t* w)
+{
+ scf_key_word_t* key;
+ int i;
+
+ for (i = 0; i < sizeof(future_key_words) / sizeof(future_key_words[0]); i++) {
+ key = &future_key_words[i];
+
+ if (w->text->len == key->len && !memcmp(w->text->data, key->text, key->len)) {
+ scf_logw("%s:%d:%d, '%s' is a key word of future std C\n",
+ w->file->data, w->line, w->pos, w->text->data);
+ break;
+ }
+ }
+}
+
static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_lex_word_t* w = words->data[words->size - 1];
scf_logd("w: '%s'\n", w->text->data);
+ warning_future_key_word(w);
+
dfa_identity_t* id = calloc(1, sizeof(dfa_identity_t));
if (!id)
return SCF_DFA_ERROR;
int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name);
+void warning_future_key_word(scf_lex_word_t* w);
+
typedef struct {
int type;
int n;
static int _base_type_filter(scf_dfa_t* dfa, scf_vector_t* words, scf_stack_t* s)
{
- if (s->size <= 1)
+ if (s->size <= 1) {
+ scf_logw("s->size: %d\n", s->size);
return 0;
+ }
scf_parse_t* parse = dfa->priv;
scf_ast_t* ast = parse->ast;
dfa_identity_t* id = NULL;
int ret;
+ warning_future_key_word(w);
+
+ scf_logi("w: %s\n", w->text->data);
+
if (s->size > 0) {
type = scf_stack_top(s);
static int _type_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- dfa_data_t* d = data;
- dfa_identity_t* id = scf_stack_top(d->current_identities);
+ scf_parse_t* parse = dfa->priv;
+ dfa_data_t* d = data;
+ dfa_identity_t* id = scf_stack_top(d->current_identities);
+ int ret;
assert(id);
if (!id->type) {
- int ret = _type_find_type(dfa, id);
+
+ if (words->size >= 3) {
+ scf_lex_word_t* name = words->data[words->size - 2];
+ scf_lex_word_t* key = words->data[words->size - 3];
+
+ if (SCF_LEX_WORD_KEY_STRUCT == key->type
+ || SCF_LEX_WORD_KEY_UNION == key->type
+ || SCF_LEX_WORD_KEY_CLASS == key->type) {
+
+ ret = __class_add_type(parse->ast, key, name);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ ret = _type_find_type(dfa, id);
if (ret < 0) {
scf_loge("\n");
return ret;
// const pointer, like 'uint8_t* const p'
scf_dfa_node_add_child(star, vconst);
scf_dfa_node_add_child(vconst, var_name);
+ scf_dfa_node_add_child(vconst, star);
// multi-return-value function
scf_dfa_node_add_child(base_type, comma);
scf_lex_word_t* w = words->data[words->size - 1];
if (d->current_va_start
+ || d->current_va_copy
|| d->current_va_arg
|| d->current_va_end) {
scf_loge("recursive 'va_start' in file: %s, line %d\n", w->file->data, w->line);
static int _va_arg_action_copy(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
+ scf_parse_t* parse = dfa->priv;
+ dfa_data_t* d = data;
scf_lex_word_t* w = words->data[words->size - 1];
- scf_loge("%s:%d:%d, NOT support 'va_copy'\n", w->file->data, w->line, w->pos);
- return SCF_DFA_ERROR;
+ if (d->current_va_start
+ || d->current_va_copy
+ || d->current_va_arg
+ || d->current_va_end) {
+ scf_loge("recursive 'va_copy' in file: %s, line %d\n", w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ scf_node_t* node = scf_node_alloc(w, SCF_OP_VA_COPY, NULL);
+ if (!node)
+ return SCF_DFA_ERROR;
+
+ scf_node_add_child((scf_node_t*)parse->ast->current_block, node);
+
+ d->current_va_copy = node;
+
+ return SCF_DFA_NEXT_WORD;
}
static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
scf_lex_word_t* w = words->data[words->size - 1];
if (d->current_va_start
+ || d->current_va_copy
|| d->current_va_arg
|| d->current_va_end) {
scf_loge("recursive 'va_arg' in file: %s, line %d\n", w->file->data, w->line);
scf_lex_word_t* w = words->data[words->size - 1];
if (d->current_va_start
+ || d->current_va_copy
|| d->current_va_arg
|| d->current_va_end) {
scf_loge("recursive 'va_end' in file: %s, line %d\n", w->file->data, w->line);
scf_lex_word_t* w = words->data[words->size - 1];
assert(d->current_va_start
+ || d->current_va_copy
|| d->current_va_arg
|| d->current_va_end);
&& SCF_VAR_I8 != fmt->type
&& SCF_VAR_U8 != fmt->type) {
- scf_loge("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data);
- return SCF_DFA_ERROR;
+ scf_logw("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data);
+ return SCF_DFA_NEXT_SYNTAX;
}
if (scf_variable_nb_pointers(fmt) != 1) {
scf_ast_t* ast = parse->ast;
dfa_identity_t* id = scf_stack_top(d->current_identities);
dfa_identity_t* id0 = NULL;
+ scf_lex_word_t* w = NULL;
scf_variable_t* v = NULL;
scf_type_t* t = NULL;
- if (id && id->identity) {
+ if (id) {
+ if (id->identity) {
+ w = id->identity;
- v = scf_scope_find_variable(ast->current_block->scope, id->identity->text->data);
- if (v) {
- scf_loge("repeated declare var '%s', line: %d\n", id->identity->text->data, id->identity->line);
- return SCF_DFA_ERROR;
+ v = scf_scope_find_variable(ast->current_block->scope, w->text->data);
+ if (v) {
+ scf_loge("repeated declare var '%s', line: %d\n", w->text->data, w->line);
+ return SCF_DFA_ERROR;
+ }
}
+ }
- assert(d->current_identities->size >= 2);
+ // anonymous var only used in function args!!
+ if (!w && !d->arg_flag)
+ return 0;
- id0 = d->current_identities->data[0];
+ assert(d->current_identities->size >= 1);
+ id0 = d->current_identities->data[0];
- assert(id0 && id0->type);
+ assert(id0 && id0->type);
- t = id0->type;
+ t = id0->type;
- int const_flag = id0->const_flag;
- int nb_pointers = id0->nb_pointers;
- void* func_ptr = id0->func_ptr;
+ int const_flag = id0->const_flag;
+ int nb_pointers = id0->nb_pointers;
+ void* func_ptr = id0->func_ptr;
- if (id0->type_def) {
- const_flag |= id0->type_def->const_flag;
- nb_pointers += id0->type_def->nb_pointers;
+ if (id0->type_def) {
+ const_flag |= id0->type_def->const_flag;
+ nb_pointers += id0->type_def->nb_pointers;
- if (!func_ptr)
- func_ptr = id0->type_def->func_ptr;
- }
+ if (!func_ptr)
+ func_ptr = id0->type_def->func_ptr;
+ }
- if (d->pf_pointers > 0) {
- nb_pointers = d->pf_pointers;
+ if (d->pf_pointers > 0) {
+ nb_pointers = d->pf_pointers;
- t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
- }
+ t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+ }
- if (SCF_VAR_VOID == t->node.type && 0 == nb_pointers) {
- scf_loge("void var must be a pointer, like 'void*'\n");
- return SCF_DFA_ERROR;
- }
+ if (SCF_VAR_VOID == t->node.type && 0 == nb_pointers) {
+ scf_loge("void var must be a pointer, like 'void*'\n");
+ return SCF_DFA_ERROR;
+ }
- if (SCF_FUNCTION_PTR == t->node.type && 0 == nb_pointers) {
- scf_loge("invalid func ptr\n");
- return SCF_DFA_ERROR;
- }
+ if (SCF_FUNCTION_PTR == t->node.type && 0 == nb_pointers) {
+ scf_loge("invalid func ptr\n");
+ return SCF_DFA_ERROR;
+ }
- scf_block_t* b = ast->current_block;
- while (b) {
- if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type)
- break;
- b = (scf_block_t*)b->node.parent;
- }
+ scf_block_t* b = ast->current_block;
+ while (b) {
+ if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type)
+ break;
- uint32_t global_flag;
- uint32_t local_flag;
- uint32_t member_flag;
+ b = (scf_block_t*)b->node.parent;
+ }
- if (!b) {
- local_flag = 0;
- global_flag = 1;
- member_flag = 0;
+ uint32_t global_flag;
+ uint32_t local_flag;
+ uint32_t member_flag;
- } else if (SCF_FUNCTION == b->node.type) {
- local_flag = 1;
- global_flag = 0;
- member_flag = 0;
+ if (!b) {
+ local_flag = 0;
+ global_flag = 1;
+ member_flag = 0;
- } else if (b->node.type >= SCF_STRUCT) {
- local_flag = 0;
- global_flag = 0;
- member_flag = 1;
+ } else if (SCF_FUNCTION == b->node.type) {
+ local_flag = 1;
+ global_flag = 0;
+ member_flag = 0;
- if (0 == nb_pointers && t->node.type >= SCF_STRUCT) {
- // if not pointer var, check if define recursive struct/union/class var
+ } else if (b->node.type >= SCF_STRUCT) {
+ local_flag = 0;
+ global_flag = 0;
+ member_flag = 1;
- if (_check_recursive((scf_type_t*)b, t, id->identity) < 0) {
+ if (0 == nb_pointers && t->node.type >= SCF_STRUCT) {
+ // if not pointer var, check if define recursive struct/union/class var
- scf_loge("recursive define when define var '%s', line: %d\n",
- id->identity->text->data, id->identity->line);
- return SCF_DFA_ERROR;
- }
- }
- }
+ if (_check_recursive((scf_type_t*)b, t, w) < 0) {
- if (id0->extern_flag) {
- if (!global_flag) {
- scf_loge("extern var must be global.\n");
+ scf_loge("%s:%d:%d, recursive define when define var '%s'\n",
+ w->file->data, w->line, w->pos, w->text->data);
return SCF_DFA_ERROR;
}
+ }
+ }
- v = scf_block_find_variable(ast->current_block, id->identity->text->data);
- if (v) {
- scf_loge("extern var already declared, line: %d\n", v->w->line);
- return SCF_DFA_ERROR;
- }
+ if (id0->extern_flag) {
+ if (!global_flag) {
+ scf_loge("%s:%d:%d, extern var '%s' MUST be global.\n", w->file->data, w->line, w->pos, w->text->data);
+ return SCF_DFA_ERROR;
}
- v = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, const_flag, nb_pointers, func_ptr);
- if (!v) {
- scf_loge("alloc var failed\n");
+ v = scf_block_find_variable(ast->current_block, w->text->data);
+ if (v) {
+ scf_loge("%s:%d:%d, extern var '%s' already declared, first here: %s:%d:%d\n",
+ w->file->data, w->line, w->pos, w->text->data,
+ v->w->file->data,
+ v->w->line,
+ v->w->pos);
return SCF_DFA_ERROR;
}
- v->local_flag = local_flag;
- v->global_flag = global_flag;
- v->member_flag = member_flag;
+ }
- v->static_flag = id0->static_flag;
- v->extern_flag = id0->extern_flag;
- v->typedef_flag = id0->typedef_flag;
+ v = SCF_VAR_ALLOC_BY_TYPE(w, t, const_flag, nb_pointers, func_ptr);
+ if (!v)
+ return SCF_DFA_ERROR;
- if (id0->type_def) {
- int i;
- scf_dimention_t* dim;
+ v->local_flag = local_flag;
+ v->global_flag = global_flag;
+ v->member_flag = member_flag;
- for (i = 0; i < id0->type_def->nb_dimentions; i++) {
- dim = &id0->type_def->dimentions[i];
+ v->static_flag = id0->static_flag;
+ v->extern_flag = id0->extern_flag;
+ v->typedef_flag = id0->typedef_flag;
- scf_variable_add_array_dimention(v, dim->num);
- }
+ if (id0->type_def) {
+ int i;
+ scf_dimention_t* dim;
+
+ for (i = 0; i < id0->type_def->nb_dimentions; i++) {
+ dim = &id0->type_def->dimentions[i];
- v->const_literal_flag = id0->type_def->nb_dimentions > 0;
+ scf_variable_add_array_dimention(v, dim->num);
}
- scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d, var: %s, line:%d, pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
- v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions,
- v->w->text->data, v->w->line, v->w->pos,
- v->local_flag, v->global_flag, v->member_flag,
- v->extern_flag, v->static_flag);
+ v->const_literal_flag = id0->type_def->nb_dimentions > 0;
+ }
+
+#if 1
+ scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d",
+ v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions);
- scf_scope_push_var(ast->current_block->scope, v);
+ if (v->w)
+ printf(", var: '%s', line:%d, pos:%d", v->w->text->data, v->w->line, v->w->pos);
+ else
+ printf(", var: 'anonymous', line:%d, pos:%d", id0->type_w->line, id0->type_w->pos);
- d->current_var = v;
- d->current_var_w = id->identity;
- id0->nb_pointers = 0;
- id0->const_flag = 0;
- id0->static_flag = 0;
- id0->extern_flag = 0;
+ printf(", local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
+ v->local_flag, v->global_flag, v->member_flag,
+ v->extern_flag, v->static_flag);
+#endif
+
+ scf_scope_push_var(ast->current_block->scope, v);
+
+ d->current_var = v;
+ d->current_var_w = w;
+ id0->nb_pointers = 0;
+ id0->const_flag = 0;
+ id0->static_flag = 0;
+ id0->extern_flag = 0;
+
+ if (d->current_identities->size >= 2) {
scf_stack_pop(d->current_identities);
+
free(id);
id = NULL;
}
static int _dfa_init_syntax_var(scf_dfa_t* dfa)
{
- SCF_DFA_GET_MODULE_NODE(dfa, var, comma, comma);
- SCF_DFA_GET_MODULE_NODE(dfa, var, semicolon, semicolon);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, comma, comma);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, semicolon, semicolon);
- SCF_DFA_GET_MODULE_NODE(dfa, var, ls, ls);
- SCF_DFA_GET_MODULE_NODE(dfa, var, rs, rs);
- SCF_DFA_GET_MODULE_NODE(dfa, var, assign, assign);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, ls, ls);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, rs, rs);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, assign, assign);
- SCF_DFA_GET_MODULE_NODE(dfa, var, colon, colon);
- SCF_DFA_GET_MODULE_NODE(dfa, var, bits, bits);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, colon, colon);
+ SCF_DFA_GET_MODULE_NODE(dfa, var, bits, bits);
- SCF_DFA_GET_MODULE_NODE(dfa, type, star, star);
- SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity);
+ SCF_DFA_GET_MODULE_NODE(dfa, type, star, star);
+ SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity);
+ SCF_DFA_GET_MODULE_NODE(dfa, type, base_type, base_type);
+ SCF_DFA_GET_MODULE_NODE(dfa, identity, identity, type_name);
- SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr);
+ SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr);
- SCF_DFA_GET_MODULE_NODE(dfa, init_data, entry, init_data);
- SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb, init_rb);
+ SCF_DFA_GET_MODULE_NODE(dfa, init_data, entry, init_data);
+ SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb, init_rb);
scf_dfa_node_add_child(identity, comma);
scf_dfa_node_add_child(rs, comma);
scf_dfa_node_add_child(rs, semicolon);
+ // anonymous array var, used for function args.
+ scf_dfa_node_add_child(base_type, ls);
+ scf_dfa_node_add_child(type_name, ls);
+ scf_dfa_node_add_child(star, ls);
+
// bits
scf_dfa_node_add_child(identity, colon);
scf_dfa_node_add_child(colon, bits);
assert(v0);
if (scf_variable_nb_pointers(v0) <= 0) {
- scf_loge("index out\n");
- return -1;
+// scf_loge("index out\n");
+// return -1;
}
scf_handler_data_t* d = data;
static int _scf_op_const_address_of(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
+ assert(1 == nb_nodes);
+
+ scf_node_t* child = nodes[0];
+ scf_node_t* parent = nodes[0]->parent;
+ scf_variable_t* result = _scf_operand_get(parent);
+ scf_variable_t* type;
+ scf_variable_t* member;
+ scf_variable_t* r = NULL;
+
+ while (SCF_OP_EXPR == child->type)
+ child = child->nodes[0];
+
+ if (SCF_OP_POINTER == child->type) {
+ assert(2 == child->nb_nodes);
+
+ type = _scf_operand_get(child->nodes[0]);
+ member = _scf_operand_get(child->nodes[1]);
+
+ if (scf_variable_const(type)) {
+
+ r = scf_variable_ref(result);
+
+ r->data.u64 = type->data.u64 + member->offset;
+ r->const_flag = 1;
+ r->const_literal_flag = 1;
+
+ scf_node_free_data(parent);
+
+ parent->type = r->type;
+ parent->var = r;
+ }
+
+ } else if (SCF_OP_ARRAY_INDEX == child->type) {
+ assert(2 == child->nb_nodes);
+
+ type = _scf_operand_get(child->nodes[0]);
+ member = _scf_operand_get(child->nodes[1]);
+
+ if (scf_variable_const(type)
+ && !type->global_flag
+ && !type->member_flag
+ && !type->local_flag
+ && scf_variable_const_integer(member)) {
+
+ r = scf_variable_ref(result);
+
+ r->data.u64 = type->data.u64 + member->data.u64 * type->data_size;
+ r->const_flag = 1;
+ r->const_literal_flag = 1;
+
+ scf_node_free_data(parent);
+
+ parent->type = r->type;
+ parent->var = r;
+
+ scf_logd("type->data.p: %p, type->data_size: %d, member->data.u64: %ld, r->data.p: %p\n",
+ type->data.p, type->data_size, member->data.u64, r->data.p);
+ }
+ }
+
return 0;
}
scf_loge("\n");
return ret;
}
+
+ r->data_size = result->data_size;
r->const_flag = 1;
if (parent->w)
SCF_XCHG(r->w, parent->w);
scf_node_free_data(parent);
+
parent->type = r->type;
parent->var = r;
}
return 0;
}
+static int _scf_op_const_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ return 0;
+}
+
static int _scf_op_const_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
return 0;
[SCF_OP_NEW ] = _scf_op_const_new,
[SCF_OP_VA_START ] = _scf_op_const_va_start,
+ [SCF_OP_VA_COPY ] = _scf_op_const_va_copy,
[SCF_OP_VA_ARG ] = _scf_op_const_va_arg,
[SCF_OP_VA_END ] = _scf_op_const_va_end,
}
ret = _semantic_find_proper_function(ast, class, "__init", argv, &finit);
- scf_vector_free(argv);
-
if (ret < 0) {
- scf_loge("init function of class '%s' not found\n", v0->w->text->data);
+ scf_string_t* signature = NULL;
+
+ ret = scf_function_signature2(&signature, ast, class, "__init", argv);
+
+ if (signature) {
+ scf_loge("init function '%s' of class '%s' not found\n", signature->data, v0->w->text->data);
+
+ scf_string_free(signature);
+ } else
+ scf_loge("init function '__init' of class '%s' not found\n", v0->w->text->data);
+
+ scf_vector_free(argv);
scf_node_free(nthis);
return -1;
}
v0->func_ptr = finit;
+ scf_vector_free(argv);
+ argv = NULL;
+
ret = _semantic_add_var(&nsize, ast, parent, v0->w, SCF_VAR_INT, 1, 0, NULL);
if (ret < 0) {
scf_node_free(nthis);
return 0;
}
+static int _scf_op_semantic_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ if (2 != nb_nodes) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int _scf_op_semantic_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
if (2 != nb_nodes) {
assert(t);
scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(nodes[0]->parent->w, t, 0, v->nb_pointers, v->func_ptr);
-
if (!r)
return -ENOMEM;
[SCF_OP_NEW ] = _scf_op_semantic_new,
[SCF_OP_VA_START ] = _scf_op_semantic_va_start,
+ [SCF_OP_VA_COPY ] = _scf_op_semantic_va_copy,
[SCF_OP_VA_ARG ] = _scf_op_semantic_va_arg,
[SCF_OP_VA_END ] = _scf_op_semantic_va_end,
for (j = 0; j < f->text_relas->size; j++) {
r = f->text_relas->data[j];
- if (scf_function_signature(parse->ast, r->func) < 0) {
+ if (scf_function_signature(parse->ast, r->func, NULL) < 0) {
scf_loge("\n");
goto error;
}
return ret;
}
- if (scf_function_signature(parse->ast, f) < 0)
+ if (scf_function_signature(parse->ast, f, NULL) < 0)
return -ENOMEM;
int ret = _fill_function_inst(code, f, offset, parse);
uint32_t extern_flag:1;
uint32_t static_flag:1;
uint32_t inline_flag:1;
+ uint32_t arg_flag:1;
uint32_t var_semicolon_flag:1;
--- /dev/null
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_ptrdiff_t
+#define __NEED_size_t
+#define __NEED_wchar_t
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#define __NEED_max_align_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if __GNUC__ > 3
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#else
+#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
+#endif
+
+#endif
--- /dev/null
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi (const char *);
+long atol (const char *);
+long long atoll (const char *);
+double atof (const char *);
+
+float strtof (const char *__restrict, char **__restrict);
+double strtod (const char *__restrict, char **__restrict);
+long double strtold (const char *__restrict, char **__restrict);
+
+long strtol (const char *__restrict, char **__restrict, int);
+unsigned long strtoul (const char *__restrict, char **__restrict, int);
+long long strtoll (const char *__restrict, char **__restrict, int);
+unsigned long long strtoull (const char *__restrict, char **__restrict, int);
+
+int rand (void);
+void srand (unsigned);
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *aligned_alloc(size_t, size_t);
+
+_Noreturn void abort (void);
+int atexit (void (*) (void));
+_Noreturn void exit (int);
+_Noreturn void _Exit (int);
+int at_quick_exit (void (*) (void));
+_Noreturn void quick_exit (int);
+
+char *getenv (const char *);
+
+int system (const char *);
+
+void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+
+int abs (int);
+long labs (long);
+long long llabs (long long);
+
+typedef struct { int quot, rem; } div_t;
+typedef struct { long quot, rem; } ldiv_t;
+typedef struct { long long quot, rem; } lldiv_t;
+
+div_t div (int, int);
+ldiv_t ldiv (long, long);
+lldiv_t lldiv (long long, long long);
+
+int mblen (const char *, size_t);
+int mbtowc (wchar_t *__restrict, const char *__restrict, size_t);
+int wctomb (char *, wchar_t);
+size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
+size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+
+int posix_memalign (void **, size_t, size_t);
+int setenv (const char *, const char *, int);
+int unsetenv (const char *);
+int mkstemp (char *);
+int mkostemp (char *, int);
+char *mkdtemp (char *);
+int getsubopt (char **, char *const *, char **);
+int rand_r (unsigned *);
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *realpath (const char *__restrict, char *__restrict);
+long int random (void);
+void srandom (unsigned int);
+char *initstate (unsigned int, char *, size_t);
+char *setstate (char *);
+int putenv (char *);
+int posix_openpt (int);
+int grantpt (int);
+int unlockpt (int);
+char *ptsname (int);
+char *l64a (long);
+long a64l (const char *);
+void setkey (const char *);
+double drand48 (void);
+double erand48 (unsigned short [3]);
+long int lrand48 (void);
+long int nrand48 (unsigned short [3]);
+long mrand48 (void);
+long jrand48 (unsigned short [3]);
+void srand48 (long);
+unsigned short *seed48 (unsigned short [3]);
+void lcong48 (unsigned short [7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char *mktemp (char *);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+int getloadavg(double *, int);
+int clearenv(void);
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+void *reallocarray (void *, size_t, size_t);
+void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char *, size_t);
+char *ecvt(double, int, int *, int *);
+char *fcvt(double, int, int *, int *);
+char *gcvt(double, int, char *);
+char *secure_getenv(const char *);
+struct __locale_struct;
+float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE)
+#define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#ifndef _STRING_H
+#define _STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+void *memcpy (void *__restrict, const void *__restrict, size_t);
+void *memmove (void *, const void *, size_t);
+void *memset (void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memchr (const void *, int, size_t);
+
+char *strcpy (char *__restrict, const char *__restrict);
+char *strncpy (char *__restrict, const char *__restrict, size_t);
+
+char *strcat (char *__restrict, const char *__restrict);
+char *strncat (char *__restrict, const char *__restrict, size_t);
+
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+
+int strcoll (const char *, const char *);
+size_t strxfrm (char *__restrict, const char *__restrict, size_t);
+
+char *strchr (const char *, int);
+char *strrchr (const char *, int);
+
+size_t strcspn (const char *, const char *);
+size_t strspn (const char *, const char *);
+char *strpbrk (const char *, const char *);
+char *strstr (const char *, const char *);
+char *strtok (char *__restrict, const char *__restrict);
+
+size_t strlen (const char *);
+
+char *strerror (int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *strtok_r (char *__restrict, const char *__restrict, char **__restrict);
+int strerror_r (int, char *, size_t);
+char *stpcpy(char *__restrict, const char *__restrict);
+char *stpncpy(char *__restrict, const char *__restrict, size_t);
+size_t strnlen (const char *, size_t);
+char *strdup (const char *);
+char *strndup (const char *, size_t);
+char *strsignal(int);
+char *strerror_l (int, locale_t);
+int strcoll_l (const char *, const char *, locale_t);
+size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
+void *memmem(const void *, size_t, const void *, size_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+void *memccpy (void *__restrict, const void *__restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char *strsep(char **, const char *);
+size_t strlcat (char *, const char *, size_t);
+size_t strlcpy (char *, const char *, size_t);
+void explicit_bzero (void *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define strdupa(x) strcpy(alloca(strlen(x)+1),x)
+int strverscmp (const char *, const char *);
+char *strchrnul(const char *, int);
+char *strcasestr(const char *, const char *);
+void *memrchr(const void *, int, size_t);
+void *mempcpy(void *, const void *, size_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
intptr_t ireg;
intptr_t freg;
- intptr_t others;
};