{SCF_OP_AND_ASSIGN, "&="},
{SCF_OP_OR_ASSIGN, "|="},
+ {SCF_OP_COMMA, "comma"},
+
{SCF_OP_VA_START, "va_start"},
{SCF_OP_VA_COPY, "va_copy"},
{SCF_OP_VA_ARG, "va_arg"},
SCF_OP_Q_MASK, // ?
SCF_OP_COLON, // :
+ SCF_OP_COMMA, // , comma operator
SCF_OP_POINTER, // -> struct member
SCF_OP_DOT, // . dot
SCF_OP_VA_COPY,
SCF_OP_VA_END,
- // 49
+ // 55
SCF_OP_BLOCK, // statement block, first in fisr run
SCF_OP_IF, // if statement
SCF_OP_FOR, // for statement
SCF_N_OPS, // total operators
- // 58
+ // 70
SCF_OP_3AC_TEQ, // test if = 0
SCF_OP_3AC_CMP, // cmp > 0, < 0, = 0, etc
SCF_OP_3AC_ASSIGN_ARRAY_INDEX, // left value, a[0] = expr
SCF_OP_3AC_ADDRESS_OF_ARRAY_INDEX,
- // 97
SCF_OP_3AC_ASSIGN_POINTER, // left value, p->a = expr
SCF_OP_3AC_ADDRESS_OF_POINTER,
SCF_VAR_I64,
SCF_VAR_INTPTR = SCF_VAR_I64,
- // 122
SCF_VAR_U8,
SCF_VAR_VOID,
SCF_VAR_BIT,
if (SCF_OP_LOGIC_AND == node->type
|| SCF_OP_LOGIC_OR == node->type
|| SCF_OP_Q_MASK == node->type
+ || SCF_OP_COMMA == node->type
|| SCF_OP_INC == node->type
|| SCF_OP_DEC == node->type
|| SCF_OP_INC_POST == node->type
uint32_t _3ac_done :1; // set when node's 3ac code is made
uint32_t semi_flag :1; // set when followed by a ';'
+ uint32_t call_flag :1; // set when followed by a '(' of function call()
};
struct scf_label_s {
{"/=", "div_", SCF_OP_DIV_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"%=", "mod_", SCF_OP_MOD_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"<<=", NULL, SCF_OP_SHL_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
- {">>=", NULL, SCF_OP_SHR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {">>=", NULL, SCF_OP_SHR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"&=", "and_", SCF_OP_AND_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"|=", "or_", SCF_OP_OR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {",", NULL, SCF_OP_COMMA, 12, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+
{"{}", NULL, SCF_OP_BLOCK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{"return", NULL, SCF_OP_RETURN, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{"break", NULL, SCF_OP_BREAK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
SCF_DAG_BINARY(mul, MUL)
SCF_DAG_BINARY(div, DIV)
SCF_DAG_BINARY(mod, MOD)
+SCF_DAG_BINARY(comma, COMMA)
static int _scf_dag_op_assign(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes)
{
{SCF_OP_AND_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign},
{SCF_OP_OR_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign},
+ {SCF_OP_COMMA, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_comma},
+
{SCF_OP_3AC_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_array_index},
{SCF_OP_3AC_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_pointer},
{SCF_OP_3AC_ASSIGN_DEREFERENCE, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_dereference},
SCF_OP_BINARY(shr, SCF_OP_SHR)
SCF_OP_BINARY(bit_and, SCF_OP_BIT_AND)
SCF_OP_BINARY(bit_or, SCF_OP_BIT_OR)
+SCF_OP_BINARY(comma, SCF_OP_COMMA)
static int _scf_op_left_value_array_index(scf_ast_t* ast, int type, scf_node_t* left, scf_node_t* right, scf_handler_data_t* d)
{
[SCF_OP_AND_ASSIGN] = _scf_op_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_or_assign,
+ [SCF_OP_COMMA ] = _scf_op_comma,
+
[SCF_OP_BLOCK ] = _scf_op_block,
[SCF_OP_RETURN ] = _scf_op_return,
}
if (index0 < 0 || index1 < 0) {
- scf_loge("type update not found for type: %d, %d\n",
- v0->type, v1->type);
+
+ scf_string_t* t0 = scf_variable_type_name(ast, v0);
+ scf_string_t* t1 = scf_variable_type_name(ast, v1);
+
+ scf_loge("type update not found for type '%s' and '%s'\n", t0->data, t1->data);
+
+ scf_string_free(t0);
+ scf_string_free(t1);
return -1;
}
int scf_type_cast_check(scf_ast_t* ast, scf_variable_t* dst, scf_variable_t* src)
{
- if (!dst->const_flag && src->const_flag && !src->const_literal_flag) {
- scf_logw("type cast %s -> %s discard 'const'\n", src->w->text->data, dst->w->text->data);
- }
-
scf_string_t* dst_type = NULL;
scf_string_t* src_type = NULL;
+ if (!dst->const_flag && src->const_flag && !src->const_literal_flag) {
+
+ dst_type = scf_variable_type_name(ast, dst);
+ src_type = scf_variable_type_name(ast, src);
+
+ scf_logw("%s:%d:%d, type cast '%s -> %s' discard 'const'\n",
+ src->w->file->data,
+ src->w->line,
+ src->w->pos, src_type->data, dst_type->data);
+
+ scf_string_free(dst_type);
+ scf_string_free(src_type);
+
+ dst_type = NULL;
+ src_type = NULL;
+ }
+
int dst_nb_pointers = dst->nb_pointers + dst->nb_dimentions;
int src_nb_pointers = src->nb_pointers + src->nb_dimentions;
if (scf_type_is_integer(dst->type)) {
- if (dst->size < src->size)
- scf_logw("type cast %s -> %s discard bits, file: %s, line: %d\n",
- src->w->text->data, dst->w->text->data, src->w->file->data, src->w->line);
+ if (dst->size < src->size) {
+ dst_type = scf_variable_type_name(ast, dst);
+ src_type = scf_variable_type_name(ast, src);
+
+ scf_logw("%s:%d:%d, type cast '%s -> %s' discard bits\n",
+ src->w->file->data,
+ src->w->line,
+ src->w->pos, src_type->data, dst_type->data);
+
+ scf_string_free(dst_type);
+ scf_string_free(src_type);
+
+ dst_type = NULL;
+ src_type = NULL;
+ }
+
return 0;
}
}
return 0;
}
+
failed:
dst_type = scf_variable_type_name(ast, dst);
src_type = scf_variable_type_name(ast, src);
- scf_loge("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n",
- src->w->text->data, dst->w->text->data,
- src_type->data, dst_type->data, src->w->file->data, src->w->line);
+ scf_loge("%s:%d:%d, type cast '%s -> %s' with different type\n",
+ src->w->file->data,
+ src->w->line,
+ src->w->pos, src_type->data, dst_type->data);
scf_string_free(dst_type);
scf_string_free(src_type);
-int printf(const char* fmt, ...);
-
-#define assert(x) \
- do { \
- if (!(x)) {\
- printf("assert: '%s' failed. file: %s, line: %d\n", #x, __FILE__, __LINE__); \
- *(int*)0 = 0; \
- } \
- } while (0)
+#include<stdio.h>
+#include<assert.h>
int main()
{
- assert(1);
+ assert(0 == 1);
printf("main ok\n");
return 0;
--- /dev/null
+
+int printf(const char* fmt, ...);
+
+int main()
+{
+ int j = 1;
+
+ printf("%d\n", (++j, 4, j + 1));
+ return 0;
+}
--- /dev/null
+int main()
+{
+ *(int*)0 = 0;
+ return 0;
+}
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stddef.h>
+#include<errno.h>
+
+int main()
+{
+ FILE* fp = fopen("./no_exist.txt", "r");
+
+ printf("fp: %p, EEXIST: %d, errno: %d\n", fp, EEXIST, errno);
+
+ if (fp)
+ fclose(fp);
+ return 0;
+}
#include<stdio.h>
#include<stdlib.h>
-#include<stdarg.h>
-#include<string.h>
#include<stddef.h>
+#include<string.h>
+#include<assert.h>
+#include<errno.h>
+#include<stdarg.h>
int main()
{
return 0;
}
+static int __copy_macro_word(scf_lex_word_t** dst, scf_lex_word_t* src, scf_lex_word_t* use)
+{
+ *dst = scf_lex_word_clone(src);
+ if (!*dst)
+ return -ENOMEM;
+
+ scf_lex_word_t* w = *dst;
+
+ w->next = NULL;
+
+ if (!strcmp(w->text->data, "__LINE__"))
+ w->data.u64 = use->line;
+
+ else if (!strcmp(w->text->data, "__FILE__")) {
+
+ int ret = scf_string_copy(w->data.s, use->file);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
static int __use_macro(scf_lex_word_t** ph, scf_lex_t* lex, scf_macro_t* m, scf_vector_t* argv, scf_lex_word_t* use)
{
scf_lex_word_t** pp;
scf_lex_word_t* h = NULL;
scf_lex_word_t* p;
scf_lex_word_t* w;
- scf_lex_word_t* prev;
pp = &h;
continue;
}
- scf_logi("p: '%s', line: %d:%d, hash: %d\n", p->text->data, p->line, p->pos, hash);
+ scf_logd("p: '%s', line: %d:%d, hash: %d\n", p->text->data, p->line, p->pos, hash);
if (m->argv) {
assert(argv);
&& !w->next)
break;
- *pp = scf_lex_word_clone(w);
- if (!*pp) {
- ret = -ENOMEM;
+ ret = __copy_macro_word(pp, w, use);
+ if (ret < 0)
goto error;
- }
- if (!strcmp((*pp)->text->data, "__LINE__"))
- (*pp)->data.u64 = use->line;
-
- scf_logd("\033[32m p: '%s', line: %d:%d, hash: %d\033[0m\n", (*pp)->text->data, (*pp)->line, (*pp)->pos, hash);
+ scf_logd("\033[32m p: '%s', %s:%d:%d, hash: %d\033[0m\n", (*pp)->text->data, (*pp)->file->data, (*pp)->line, (*pp)->pos, hash);
pp = &(*pp)->next;
}
}
}
- *pp = scf_lex_word_clone(p);
- if (!*pp) {
- ret = -ENOMEM;
+ ret = __copy_macro_word(pp, p, use);
+ if (ret < 0)
goto error;
- }
-
- if (!strcmp((*pp)->text->data, "__LINE__"))
- (*pp)->data.u64 = use->line;
pp = &(*pp)->next;
scf_logd("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n",
local, f->local_vars_size, f->callee_saved_size);
- if (f->bp_used_flag || f->call_flag) {
+ if (local > 0 || f->call_flag) {
- if (f->bp_used_flag) {
+ if (local > 0) {
inst = x64_make_inst_G2E(mov, rsp, rbp);
X64_INST_ADD_CHECK(end, inst, NULL);
end->inst_bytes += inst->len;
f->init_code_bytes = 0;
- if (f->bp_used_flag || f->call_flag) {
+ if (local > 0 || f->call_flag) {
inst = x64_make_inst_G(push, rbp);
X64_INST_ADD_CHECK(f->init_code, inst, NULL);
f->init_code_bytes += inst->len;
- if (f->bp_used_flag) {
+ if (local > 0) {
inst = x64_make_inst_G2E(mov, rbp, rsp);
X64_INST_ADD_CHECK(f->init_code, inst, NULL);
f->init_code_bytes += inst->len;
- }
- if (local > 0) {
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&local, 4);
X64_INST_ADD_CHECK(f->init_code, inst, NULL);
f->init_code_bytes += inst->len;
X64_INST_OP3(bit_or, OR)
+static int _x64_inst_comma_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+ if (!c->dsts || c->dsts->size != 1)
+ return -EINVAL;
+
+ if (!c->srcs || c->srcs->size != 2)
+ return -EINVAL;
+
+ scf_x64_context_t* x64 = ctx->priv;
+ scf_function_t* f = x64->f;
+
+ scf_3ac_operand_t* dst = c->dsts->data[0];
+ scf_3ac_operand_t* src1 = c->srcs->data[1];
+
+ if (!src1 || !src1->dag_node)
+ return -EINVAL;
+
+ if (!dst || !dst->dag_node)
+ return -EINVAL;
+
+ if (dst->dag_node->var->size != src1->dag_node->var->size) {
+ scf_loge("size: %d, %d\n", dst->dag_node->var->size, src1->dag_node->var->size);
+ return -EINVAL;
+ }
+
+ if (!c->instructions) {
+ c->instructions = scf_vector_alloc();
+ if (!c->instructions)
+ return -ENOMEM;
+ }
+
+ if (scf_variable_float(src1->dag_node->var)) {
+
+ assert(scf_variable_float(dst->dag_node->var));
+
+ return _x64_inst_float_op2(SCF_X64_MOV, dst->dag_node, src1->dag_node, c, f);
+ }
+
+ return x64_inst_op2(SCF_X64_MOV, dst->dag_node, src1->dag_node, c, f);
+}
+
static int _x64_inst_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
return x64_inst_teq(ctx, c);
[SCF_OP_AND_ASSIGN ] = _x64_inst_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_inst_or_assign_handler,
+ [SCF_OP_COMMA ] = _x64_inst_comma_handler,
+
[SCF_OP_RETURN ] = _x64_inst_return_handler,
[SCF_OP_GOTO ] = _x64_inst_goto_handler,
scf_variable_t* v = src->dag_node->var;
x64_sib_t sib = {0};
- assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT);
+ //assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT);
+
+ intptr_t color = base->dag_node->color;
+ if (0 == color)
+ base->dag_node->color = -1;
int ret = x64_dereference_reg(&sib, base->dag_node, NULL, c, f);
if (ret < 0)
int is_float = scf_variable_float(v);
if (is_float)
- return _binary_assign_sib_float(sib.base, sib.index, sib.scale, sib.disp, src->dag_node, c, f, SCF_X64_MOV);
+ ret = _binary_assign_sib_float(sib.base, sib.index, sib.scale, sib.disp, src->dag_node, c, f, SCF_X64_MOV);
+ else
+ ret = _binary_assign_sib_int(&sib, src->dag_node, c, f, SCF_X64_MOV);
+
+ if (0 == color) {
+ base->dag_node->color = 0;
+
+ assert(0 == scf_vector_del(sib.base->dag_nodes, base->dag_node));
+ }
- return _binary_assign_sib_int(&sib, src->dag_node, c, f, SCF_X64_MOV);
+ return ret;
}
int x64_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c)
assert(0 != dst->color);
scf_x64_OpCode_t* OpCode = NULL;
- scf_register_t* rs = NULL;
- scf_register_t* rd = NULL;
+ scf_register_t* rs = NULL;
+ scf_register_t* rd = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
return _x64_rcg_mul_div_mod2(ctx, c, g);
}
-static int _x64_rcg_add_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = x64_rcg_make2(c, dst->dag_node, NULL);
- if (ret < 0)
- return ret;
-
- return x64_rcg_make(c, g, dst->dag_node, NULL);
+#define X64_RCG_BINARY(name) \
+static int _x64_rcg_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
+{ \
+ scf_3ac_operand_t* dst = c->dsts->data[0]; \
+ \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
+ if (ret < 0) \
+ return ret; \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
}
-static int _x64_rcg_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = x64_rcg_make2(c, dst->dag_node, NULL);
- if (ret < 0)
- return ret;
-
- return x64_rcg_make(c, g, dst->dag_node, NULL);
-}
+X64_RCG_BINARY(add)
+X64_RCG_BINARY(sub)
+X64_RCG_BINARY(bit_and)
+X64_RCG_BINARY(bit_or)
+X64_RCG_BINARY(comma)
static int _x64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
return _x64_rcg_shift2(ctx, c, g);
}
-static int _x64_rcg_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = x64_rcg_make2(c, dst->dag_node, NULL);
- if (ret < 0)
- return ret;
-
- return x64_rcg_make(c, g, dst->dag_node, NULL);
-}
-
-static int _x64_rcg_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = x64_rcg_make2(c, dst->dag_node, NULL);
- if (ret < 0)
- return ret;
-
- return x64_rcg_make(c, g, dst->dag_node, NULL);
-}
-
static int _x64_rcg_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
int ret = x64_rcg_make2(c, NULL, NULL);
[SCF_OP_AND_ASSIGN ] = _x64_rcg_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_rcg_or_assign_handler,
+ [SCF_OP_COMMA ] = _x64_rcg_comma_handler,
+
[SCF_OP_RETURN ] = _x64_rcg_return_handler,
[SCF_OP_3AC_CMP ] = _x64_rcg_cmp_handler,
static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag);
+void scf_dfa_disable_hook_w(scf_dfa_t* dfa, int hook_type, void* word)
+{
+ if (hook_type < 0 || hook_type >= SCF_DFA_HOOK_NB)
+ return;
+
+ scf_dfa_hook_t* h = dfa->hooks[hook_type];
+
+ while (h) {
+ if (h->node->is && h->node->is(dfa, word)) {
+ h->disable_flag = 1;
+ break;
+ }
+
+ h = h->next;
+ }
+}
+
+void scf_dfa_enable_hook_w(scf_dfa_t* dfa, int hook_type, void* word)
+{
+ if (hook_type < 0 || hook_type >= SCF_DFA_HOOK_NB)
+ return;
+
+ scf_dfa_hook_t* h = dfa->hooks[hook_type];
+
+ while (h) {
+ if (h->node->is && h->node->is(dfa, word)) {
+ h->disable_flag = 0;
+ break;
+ }
+
+ h = h->next;
+ }
+}
+
void scf_dfa_disable_hook(scf_dfa_hook_t* h, const char* name)
{
while (h) {
if (!pre_hook_flag) {
scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_POST]), w);
- if (hook) {
+
+ if (hook && !hook->disable_flag) {
+
scf_dfa_node_t* hook_node = hook->node;
scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_POST]), hook->next);
if (SCF_DFA_OK == ret) {
scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
- while (*pp) {
+ while (*pp && !(*pp)->disable_flag) {
+
scf_dfa_hook_t* hook = *pp;
scf_dfa_node_t* hook_node = hook->node;
void scf_dfa_del_hook (scf_dfa_hook_t** pp, scf_dfa_hook_t* sentinel);
void scf_dfa_del_hook_by_name(scf_dfa_hook_t** pp, const char* name);
-void scf_dfa_disable_hook(scf_dfa_hook_t* h, const char* name);
-void scf_dfa_enable_hook (scf_dfa_hook_t* h, const char* name);
+void scf_dfa_disable_hook (scf_dfa_hook_t* h, const char* name);
+void scf_dfa_enable_hook (scf_dfa_hook_t* h, const char* name);
+
+void scf_dfa_disable_hook_w(scf_dfa_t* dfa, int hook_type, void* word);
+void scf_dfa_enable_hook_w (scf_dfa_t* dfa, int hook_type, void* word);
#endif
int nb_lps;
int nb_rps;
+ uint32_t op_comma_flag:1;
+
scf_node_t* func;
scf_node_t* call;
scf_vector_t* argv;
scf_logd("d->expr: %p, OP: %d\n", d->expr, d->expr->type);
- cd->func = node_pf;
- cd->call = node_call;
- cd->parent_expr = d->expr;
- d->expr = NULL;
+ scf_expr_t* grand = scf_stack_top(d->lp_exprs);
+ if (grand) {
+ grand->call_flag = 1;
+
+ scf_logi("grand: %p, grand->call_flag: %d\n", grand, grand->call_flag);
+ }
+
+ cd->func = node_pf;
+ cd->call = node_call;
+ cd->parent_expr = d->expr;
+ d->expr = NULL;
d->expr_local_flag++;
+ cd->op_comma_flag = d->op_comma_flag;
+ d ->op_comma_flag = 0;
+
scf_stack_push(s, cd);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "call_rp"), SCF_DFA_HOOK_POST);
scf_stack_pop(s);
- scf_logd("d->expr: %p\n", d->expr);
+ scf_logd("cd->parent_expr: %p, d->expr: %p\n", cd->parent_expr, d->expr);
if (cd->parent_expr) {
if (cd->func)
d->expr = cd->call;
d->expr_local_flag--;
+ d->op_comma_flag = cd->op_comma_flag;
scf_logd("d->expr: %p\n", d->expr);
+ scf_expr_t* grand = scf_stack_top(d->lp_exprs);
+ if (grand) {
+ grand->call_flag = 0;
+
+ scf_logi("grand: %p, grand->call_flag: %d\n", grand, grand->call_flag);
+ }
+
free(cd);
cd = NULL;
typedef struct {
scf_stack_t* ls_exprs;
- scf_stack_t* lp_exprs;
scf_block_t* parent_block;
scf_type_t* current_struct;
+ scf_lex_word_t* op_comma;
+
+ int n_lps;
+ int n_rps;
+
+ int n_lss;
+ int n_rss;
} expr_module_data_t;
int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
{
scf_lex_word_t* w = word;
- if (SCF_LEX_WORD_LS == w->type
+ if (SCF_LEX_WORD_COMMA == w->type
+ || SCF_LEX_WORD_LS == w->type
|| SCF_LEX_WORD_RS == w->type
|| SCF_LEX_WORD_LP == w->type
|| SCF_LEX_WORD_RP == w->type)
dfa_data_t* d = data;
expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
+ md->n_lps++;
+
+ d->op_comma_flag = 1;
+
scf_expr_t* e = scf_expr_alloc();
if (!e) {
scf_loge("\n");
return SCF_DFA_ERROR;
}
- scf_logi("d->expr: %p, e: %p\n", d->expr, e);
+ scf_logi("d->expr: %p, e: %p, d->op_comma_flag: %d\n", d->expr, e, d->op_comma_flag);
- scf_stack_push(md->lp_exprs, d->expr);
+ scf_stack_push(d->lp_exprs, d->expr);
d->expr = e;
if (md->parent_block) {
expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
dfa_identity_t* id = scf_stack_top(d->current_identities);
+ md->n_rps++;
+
+ if (md->n_rps >= md->n_lps) {
+ md->n_rps = 0;
+ md->n_lps = 0;
+
+ assert(!md->op_comma);
+
+ d->op_comma_flag = 0;
+ }
+ scf_logi("d->op_comma_flag: %d\n", d->op_comma_flag);
+
if (!id) {
scf_loge("\n");
return SCF_DFA_ERROR;
}
// '(' lp action pushed a expr before
- e = scf_stack_pop(md->lp_exprs);
+ e = scf_stack_pop(d->lp_exprs);
assert(e);
ret = scf_expr_add_node(e, cast);
expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
dfa_identity_t* id = scf_stack_top(d->current_identities);
+ md->n_rps++;
+
+ if (md->n_rps >= md->n_lps) {
+ md->n_rps = 0;
+ md->n_lps = 0;
+
+ if (md->op_comma) {
+ scf_dfa_enable_hook_w(dfa, SCF_DFA_HOOK_PRE, md->op_comma);
+ scf_dfa_enable_hook_w(dfa, SCF_DFA_HOOK_POST, md->op_comma);
+
+ md->op_comma = NULL;
+ }
+
+ d->op_comma_flag = 0;
+ }
+ scf_logi("d->op_comma_flag: %d\n", d->op_comma_flag);
+
if (id && id->identity) {
scf_variable_t* v = NULL;
md->parent_block = NULL;
}
- scf_expr_t* parent = scf_stack_pop(md->lp_exprs);
-
- scf_logd("d->expr: %p, d->expr->parent: %p, lp: %p\n\n", d->expr, d->expr->parent, parent);
+ scf_expr_t* parent = scf_stack_top(d->lp_exprs);
if (parent) {
- scf_expr_add_node(parent, d->expr);
- d->expr = parent;
+ scf_logi("d->expr: %p, parent: %p, parent->call_flag: %d\n\n", d->expr, parent, parent->call_flag);
+
+ if (!parent->call_flag) {
+ scf_stack_pop(d->lp_exprs);
+
+ scf_expr_add_node(parent, d->expr);
+ d->expr = parent;
+ }
}
return SCF_DFA_NEXT_WORD;
int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
{
- expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
- dfa_identity_t* id = scf_stack_top(d->current_identities);
-
- if (id && id->identity) {
-
- int ret = _expr_add_var(parse, d);
-
- if (SCF_DFA_OK != ret)
- return ret;
- }
-
- if (md->parent_block) {
- parse->ast->current_block = md->parent_block;
- md->parent_block = NULL;
- }
-
scf_logd("d->expr: %p\n", d->expr);
if (d->expr) {
static int _expr_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- scf_parse_t* parse = dfa->priv;
- dfa_data_t* d = data;
+ scf_parse_t* parse = dfa->priv;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ dfa_data_t* d = data;
+ expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
+ dfa_identity_t* id = scf_stack_top(d->current_identities);
+ int ret;
- int ret = _expr_fini_expr(parse, d, 0);
+ if (id && id->identity) {
- if (SCF_DFA_OK != ret)
- return ret;
+ ret = _expr_add_var(parse, d);
+
+ if (SCF_DFA_OK != ret)
+ return ret;
+ }
+
+ if (md->parent_block) {
+ parse->ast->current_block = md->parent_block;
+ md->parent_block = NULL;
+ }
+
+ scf_logi("d->op_comma_flag: %d\n", d->op_comma_flag);
+
+ if (md->n_lps > 0 && d->op_comma_flag) {
+
+ scf_loge("op: '%s', %d:%d\n", w->text->data, w->line, w->pos);
+
+ scf_node_t* node = scf_node_alloc(w, SCF_OP_COMMA, NULL);
+ if (!node)
+ return -ENOMEM;
+
+ ret = scf_expr_add_node(d->expr, node);
+ if (ret < 0) {
+ scf_node_free(node);
+ return ret;
+ }
+
+ scf_dfa_disable_hook_w(dfa, SCF_DFA_HOOK_PRE, w);
+ scf_dfa_disable_hook_w(dfa, SCF_DFA_HOOK_POST, w);
+
+ md->op_comma = w;
+ } else {
+ ret = _expr_fini_expr(parse, d, 0);
+
+ if (SCF_DFA_OK != ret)
+ return ret;
+ }
return SCF_DFA_NEXT_WORD;
}
static int _expr_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- scf_parse_t* parse = dfa->priv;
- dfa_data_t* d = data;
+ scf_parse_t* parse = dfa->priv;
+ dfa_data_t* d = data;
+ expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
+ dfa_identity_t* id = scf_stack_top(d->current_identities);
+ int ret;
+
+ if (id && id->identity) {
- int ret = _expr_fini_expr(parse, d, 1);
+ ret = _expr_add_var(parse, d);
+
+ if (SCF_DFA_OK != ret)
+ return ret;
+ }
+
+ if (md->parent_block) {
+ parse->ast->current_block = md->parent_block;
+ md->parent_block = NULL;
+ }
+
+ ret = _expr_fini_expr(parse, d, 1);
if (SCF_DFA_OK != ret)
return ret;
}
md->ls_exprs = scf_stack_alloc();
- if (!md->ls_exprs)
- goto _ls_exprs;
+ if (!md->ls_exprs) {
+ scf_loge("\n");
- md->lp_exprs = scf_stack_alloc();
- if (!md->lp_exprs)
- goto _lp_exprs;
+ free(md);
+ return SCF_DFA_ERROR;
+ }
d->module_datas[dfa_module_expr.index] = md;
return SCF_DFA_OK;
-
-_lp_exprs:
- scf_stack_free(md->ls_exprs);
-_ls_exprs:
- scf_loge("\n");
-
- free(md);
- md = NULL;
- return SCF_DFA_ERROR;
}
static int _dfa_fini_module_expr(scf_dfa_t* dfa)
if (md->ls_exprs)
scf_stack_free(md->ls_exprs);
- if (md->lp_exprs)
- scf_stack_free(md->lp_exprs);
-
free(md);
md = NULL;
d->module_datas[dfa_module_expr.index] = NULL;
scf_lex_word_t* word_op;
+ int nb_lps;
+ int nb_rps;
} dfa_op_data_t;
static int _operator_is_key(scf_dfa_t* dfa, void* word)
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_rp"), SCF_DFA_HOOK_PRE);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_comma"), SCF_DFA_HOOK_PRE);
- d->nb_lps++;
+ opd->nb_lps++;
return SCF_DFA_NEXT_WORD;
}
dfa_op_data_t* opd = d->module_datas[dfa_module_operator.index];
scf_function_t* f = NULL;
- d->nb_rps++;
+ opd->nb_rps++;
- if (d->nb_rps < d->nb_lps) {
+ if (opd->nb_rps < opd->nb_lps) {
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_rp"), SCF_DFA_HOOK_PRE);
return SCF_DFA_NEXT_WORD;
}
opd->parent_block = NULL;
d->current_function = NULL;
- d->nb_lps = 0;
- d->nb_rps = 0;
+ opd->nb_lps = 0;
+ opd->nb_rps = 0;
return SCF_DFA_OK;
}
return -1;
}
+ parse->dfa_data->lp_exprs = scf_stack_alloc();
+ if (!parse->dfa_data->lp_exprs) {
+ scf_loge("\n");
+ return -1;
+ }
+
scf_dfa_module_t* m;
int i;
return _scf_op_const_binary(ast, nodes, nb_nodes, data);
}
+static int _scf_op_const_comma(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_node_t* node0 = nodes[0];
+ scf_node_t* node1 = nodes[1];
+ scf_node_t* parent = node1->parent;
+ scf_variable_t* r;
+
+ while (SCF_OP_EXPR == node0->type)
+ node0 = node0->nodes[0];
+
+ while (SCF_OP_EXPR == node1->type)
+ node1 = node1->nodes[0];
+
+ if (scf_type_is_var(node0->type) && scf_type_is_var(node1->type)) {
+
+ r = scf_variable_ref(node1->var);
+ if (!r->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_q_mask(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
[SCF_OP_AND_ASSIGN ] = _scf_op_const_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_const_or_assign,
+ [SCF_OP_COMMA ] = _scf_op_const_comma,
+
[SCF_OP_BLOCK ] = _scf_op_const_block,
[SCF_OP_RETURN ] = _scf_op_const_return,
[SCF_OP_BREAK ] = _scf_op_const_break,
if (n->result) {
scf_variable_free(n->result);
- n->result = 0;
+ n->result = NULL;
}
scf_variable_t** pret = d->pret;
return _scf_op_semantic_binary_interger(ast, nodes, nb_nodes, data);
}
+static int _scf_op_semantic_comma(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_handler_data_t* d = data;
+
+ scf_type_t* t = NULL;
+ scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+ scf_variable_t* v1 = _scf_operand_get(nodes[1]);
+
+ int ret = scf_ast_find_type_type(&t, ast, v1->type);
+ if (ret < 0)
+ return ret;
+
+ int const_flag = v0->const_flag && v1->const_flag;
+
+ scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(nodes[0]->parent->w, t, const_flag, v1->nb_pointers, v1->func_ptr);
+ if (!r)
+ return -ENOMEM;
+
+ *d->pret = r;
+ return 0;
+}
+
static int _scf_op_semantic_q_mask(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
[SCF_OP_AND_ASSIGN ] = _scf_op_semantic_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_semantic_or_assign,
+ [SCF_OP_COMMA ] = _scf_op_semantic_comma,
+
[SCF_OP_BLOCK ] = _scf_op_semantic_block,
[SCF_OP_RETURN ] = _scf_op_semantic_return,
[SCF_OP_BREAK ] = _scf_op_semantic_break,
struct dfa_data_s {
void** module_datas;
+ scf_stack_t* lp_exprs;
scf_expr_t* expr;
int expr_local_flag;
uint32_t inline_flag:1;
uint32_t arg_flag:1;
+ uint32_t op_comma_flag:1;
+
uint32_t var_semicolon_flag:1;
int nb_lbs;
int nb_lss;
int nb_rss;
- int nb_lps;
- int nb_rps;
+// int nb_lps;
+// int nb_rps;
};
int scf_parse_dfa_init(scf_parse_t* parse);
--- /dev/null
+#include <features.h>
+
+#undef assert
+
+#ifdef NDEBUG
+#define assert(x) (void)0
+#else
+#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0)))
+#endif
+
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
+#define static_assert _Static_assert
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_Noreturn void __assert_fail (const char *, const char *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define ENOTBLK 15
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define ETXTBSY 26
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 35
+#define ENAMETOOLONG 36
+#define ENOLCK 37
+#define ENOSYS 38
+#define ENOTEMPTY 39
+#define ELOOP 40
+#define EWOULDBLOCK EAGAIN
+#define ENOMSG 42
+#define EIDRM 43
+#define ECHRNG 44
+#define EL2NSYNC 45
+#define EL3HLT 46
+#define EL3RST 47
+#define ELNRNG 48
+#define EUNATCH 49
+#define ENOCSI 50
+#define EL2HLT 51
+#define EBADE 52
+#define EBADR 53
+#define EXFULL 54
+#define ENOANO 55
+#define EBADRQC 56
+#define EBADSLT 57
+#define EDEADLOCK EDEADLK
+#define EBFONT 59
+#define ENOSTR 60
+#define ENODATA 61
+#define ETIME 62
+#define ENOSR 63
+#define ENONET 64
+#define ENOPKG 65
+#define EREMOTE 66
+#define ENOLINK 67
+#define EADV 68
+#define ESRMNT 69
+#define ECOMM 70
+#define EPROTO 71
+#define EMULTIHOP 72
+#define EDOTDOT 73
+#define EBADMSG 74
+#define EOVERFLOW 75
+#define ENOTUNIQ 76
+#define EBADFD 77
+#define EREMCHG 78
+#define ELIBACC 79
+#define ELIBBAD 80
+#define ELIBSCN 81
+#define ELIBMAX 82
+#define ELIBEXEC 83
+#define EILSEQ 84
+#define ERESTART 85
+#define ESTRPIPE 86
+#define EUSERS 87
+#define ENOTSOCK 88
+#define EDESTADDRREQ 89
+#define EMSGSIZE 90
+#define EPROTOTYPE 91
+#define ENOPROTOOPT 92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP 95
+#define ENOTSUP EOPNOTSUPP
+#define EPFNOSUPPORT 96
+#define EAFNOSUPPORT 97
+#define EADDRINUSE 98
+#define EADDRNOTAVAIL 99
+#define ENETDOWN 100
+#define ENETUNREACH 101
+#define ENETRESET 102
+#define ECONNABORTED 103
+#define ECONNRESET 104
+#define ENOBUFS 105
+#define EISCONN 106
+#define ENOTCONN 107
+#define ESHUTDOWN 108
+#define ETOOMANYREFS 109
+#define ETIMEDOUT 110
+#define ECONNREFUSED 111
+#define EHOSTDOWN 112
+#define EHOSTUNREACH 113
+#define EALREADY 114
+#define EINPROGRESS 115
+#define ESTALE 116
+#define EUCLEAN 117
+#define ENOTNAM 118
+#define ENAVAIL 119
+#define EISNAM 120
+#define EREMOTEIO 121
+#define EDQUOT 122
+#define ENOMEDIUM 123
+#define EMEDIUMTYPE 124
+#define ECANCELED 125
+#define ENOKEY 126
+#define EKEYEXPIRED 127
+#define EKEYREVOKED 128
+#define EKEYREJECTED 129
+#define EOWNERDEAD 130
+#define ENOTRECOVERABLE 131
+#define ERFKILL 132
+#define EHWPOISON 133
--- /dev/null
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/errno.h>
+
+#ifdef __GNUC__
+__attribute__((const))
+#endif
+int *__errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef _GNU_SOURCE
+extern char *program_invocation_short_name, *program_invocation_name;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+