}
}
- c2->label = c->label;
- c2->error = c->error;
-
+ c2->label = c->label;
c2->origin = c;
return c2;
}
c->op = scf_3ac_find_operator(type);
c->label = l;
- c->error = err;
c->dsts = scf_vector_alloc();
if (!c->dsts) {
typedef struct scf_3ac_operand_s scf_3ac_operand_t;
struct scf_3ac_operator_s {
- int type;
- const char* name;
+ int type;
+ const char* name;
};
struct scf_3ac_operand_s {
scf_vector_t* srcs; // src operands, usually 2
scf_label_t* label; // only for 'goto' to find the destination to go
- scf_node_t* error; // only for 'error'
scf_3ac_code_t* origin;
int scf_ast_open(scf_ast_t** past)
{
- assert(past);
+ if (!past)
+ return -EINVAL;
scf_ast_t* ast = calloc(1, sizeof(scf_ast_t));
- assert(ast);
+ if (!ast)
+ return -ENOMEM;
ast->root_block = scf_block_alloc_cstr("global");
+ if (!ast->root_block) {
+ free(ast);
+ return -ENOMEM;
+ }
+
ast->root_block->node.root_flag = 1;
ast->global_consts = scf_vector_alloc();
scf_block_t* scf_block_alloc(scf_lex_word_t* w)
{
scf_block_t* b = calloc(1, sizeof(scf_block_t));
- assert(b);
+ if (!b)
+ return NULL;
- b->node.type = SCF_OP_BLOCK;
+ b->scope = scf_scope_alloc(w, "block");
+ if (!b->scope) {
+ free(b);
+ return NULL;
+ }
- if (w)
+ if (w) {
b->node.w = scf_lex_word_clone(w);
- else
- b->node.w = NULL;
- b->scope = scf_scope_alloc(w, "block");
+ if (!b->node.w) {
+ scf_scope_free(b->scope);
+ free(b);
+ return NULL;
+ }
+ }
+ b->node.type = SCF_OP_BLOCK;
return b;
}
scf_block_t* scf_block_alloc_cstr(const char* name)
{
scf_block_t* b = calloc(1, sizeof(scf_block_t));
- assert(b);
+ if (!b)
+ return NULL;
- b->node.type = SCF_OP_BLOCK;
b->name = scf_string_cstr(name);
+ if (!b->name) {
+ free(b);
+ return NULL;
+ }
+
b->scope = scf_scope_alloc(NULL, name);
+ if (!b->scope) {
+ scf_string_free(b->name);
+ free(b);
+ return NULL;
+ }
+ b->node.type = SCF_OP_BLOCK;
return b;
}
void scf_block_free(scf_block_t* b)
{
- assert(b);
- assert(b->scope);
+ if (b) {
+ scf_scope_free(b->scope);
+ b->scope = NULL;
- scf_scope_free(b->scope);
- b->scope = NULL;
+ if (b->name) {
+ scf_string_free(b->name);
+ b->name = NULL;
+ }
- if (b->name) {
- scf_string_free(b->name);
- b->name = NULL;
- }
+ if (b->w_end) {
+ scf_lex_word_free(b->w_end);
+ b->w_end = NULL;
+ }
- if (b->w_end) {
- scf_lex_word_free(b->w_end);
- b->w_end = NULL;
+ scf_node_free((scf_node_t*)b);
}
-
- scf_node_free((scf_node_t*)b);
}
scf_type_t* scf_block_find_type(scf_block_t* b, const char* name)
#include"scf_string.h"
#include"scf_list.h"
-enum scf_lex_words {
+enum scf_lex_words
+{
SCF_LEX_WORD_PLUS = 0, // +
SCF_LEX_WORD_MINUS, // -
SCF_LEX_WORD_STAR, // *
SCF_LEX_WORD_CONST_U64,
// identity
- SCF_LEX_WORD_ID, // identity, start of _, a-z, A-Z, may include 0-9
+ SCF_LEX_WORD_ID, // identity, start of _, a-z, A-Z, may include 0-9
};
typedef struct {
return SCF_LEX_WORD_KEY_CHAR <= w->type && SCF_LEX_WORD_KEY_VOID >= w->type;
}
-scf_lex_word_t* scf_lex_word_alloc(scf_string_t* file, int line, int pos, int type);
-scf_lex_word_t* scf_lex_word_clone(scf_lex_word_t* w);
-void scf_lex_word_free(scf_lex_word_t* w);
+scf_lex_word_t* scf_lex_word_alloc(scf_string_t* file, int line, int pos, int type);
+scf_lex_word_t* scf_lex_word_clone(scf_lex_word_t* w);
+void scf_lex_word_free (scf_lex_word_t* w);
#endif
-
scf_scope_t* scf_scope_alloc(scf_lex_word_t* w, const char* name)
{
scf_scope_t* scope = calloc(1, sizeof(scf_scope_t));
- assert(scope);
+ if (!scope)
+ return NULL;
scope->name = scf_string_cstr(name);
+ if (!scope->name) {
+ free(scope);
+ return NULL;
+ }
+
+ scope->vars = scf_vector_alloc();
+ if (!scope->vars) {
+ scf_string_free(scope->name);
+ free(scope);
+ return NULL;
+ }
if (w) {
scope->w = scf_lex_word_clone(w);
- }
- scope->vars = scf_vector_alloc();
+ if (!scope->w) {
+ scf_vector_free(scope->vars);
+ scf_string_free(scope->name);
+ free(scope);
+ return NULL;
+ }
+ }
scf_list_init(&scope->list);
scf_list_init(&scope->type_list_head);
void scf_scope_free(scf_scope_t* scope)
{
- assert(scope);
+ if (scope) {
+ scf_string_free(scope->name);
+ scope->name = NULL;
- assert(scope->name);
- scf_string_free(scope->name);
- scope->name = NULL;
+ if (scope->w)
+ scf_lex_word_free(scope->w);
- if (scope->w)
- scf_lex_word_free(scope->w);
+ scf_vector_clear(scope->vars, (void (*)(void*))scf_variable_free);
+ scf_vector_free(scope->vars);
+ scope->vars = NULL;
- scf_vector_clear(scope->vars, (void (*)(void*))scf_variable_free);
- scf_vector_free(scope->vars);
- scope->vars = NULL;
+ scf_list_clear(&scope->type_list_head, scf_type_t, list, scf_type_free);
+ scf_list_clear(&scope->function_list_head, scf_function_t, list, scf_function_free);
- scf_list_clear(&scope->type_list_head, scf_type_t, list, scf_type_free);
- scf_list_clear(&scope->function_list_head, scf_function_t, list, scf_function_free);
-
- free(scope);
- scope = NULL;
+ free(scope);
+ }
}
scf_type_t* scf_scope_find_type(scf_scope_t* scope, const char* name)
l != scf_list_sentinel(&scope->type_list_head); l = scf_list_next(l)) {
scf_type_t* t = scf_list_data(l, scf_type_t, list);
- if (type == t->type) {
+ if (type == t->type)
return t;
- }
}
return NULL;
}
scf_variable_t* v = scope->vars->data[i];
//printf("%s(),%d, scope: %p, name: %s, v: %s\n", __func__, __LINE__, scope, name, v->w->text->data);
- if (v->w && !strcmp(name, v->w->text->data)) {
+ if (v->w && !strcmp(name, v->w->text->data))
return v;
- }
}
return NULL;
}
scf_label_t* label = scf_list_data(l, scf_label_t, list);
- if (!strcmp(name, label->w->text->data)) {
+ if (!strcmp(name, label->w->text->data))
return label;
- }
}
return NULL;
}
*pfunctions = vec;
return 0;
}
-
-scf_type_t* scf_scope_list_find_type(scf_list_t* h, const char* name)
-{
- scf_list_t* l;
- for (l = scf_list_head(h);
- l != scf_list_sentinel(h); l = scf_list_next(l)) {
-
- scf_scope_t* scope = scf_list_data(l, scf_scope_t, list);
- scf_list_t* l1;
-
- for (l1 = scf_list_head(&scope->type_list_head);
- l1 != scf_list_sentinel(&scope->type_list_head); l1 = scf_list_next(l1)) {
- scf_type_t* t = scf_list_data(l1, scf_type_t, list);
-
- if (!strcmp(name, t->name->data)) {
- return t;
- }
- }
- }
- return NULL;
-}
-
int scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const char* name, scf_vector_t* argv);
-scf_type_t* scf_scope_list_find_type(scf_list_t* h, const char* name);
-
void scf_scope_push_label(scf_scope_t* scope, scf_label_t* l);
scf_label_t* scf_scope_find_label(scf_scope_t* scope, const char* name);
#endif
-
scf_type_t* scf_type_alloc(scf_lex_word_t* w, const char* name, int type, int size)
{
scf_type_t* t = calloc(1, sizeof(scf_type_t));
- assert(t);
+ if (!t)
+ return NULL;
t->type = type;
t->node.type = type;
- t->name = scf_string_cstr(name);
-// printf("%s(),%d, t: %p, t->name: %p, t->name->data: %s, t->type: %d\n", __func__, __LINE__, t, t->name, t->name->data, t->type);
- if (w)
+ t->name = scf_string_cstr(name);
+ if (!t->name) {
+ free(t);
+ return NULL;
+ }
+
+ if (w) {
t->w = scf_lex_word_clone(w);
- else
- t->w = NULL;
+ if (!t->w) {
+ scf_string_free(t->name);
+ free(t);
+ return NULL;
+ }
+ }
t->size = size;
return t;
void scf_type_free(scf_type_t* t)
{
- assert(t);
-
- scf_string_free(t->name);
- t->name = NULL;
-
- if (t->w) {
- scf_lex_word_free(t->w);
- t->w = NULL;
- }
-
- if (t->scope) {
- scf_scope_free(t->scope);
- t->scope = NULL;
+ if (t) {
+ scf_string_free(t->name);
+ t->name = NULL;
+
+ if (t->w) {
+ scf_lex_word_free(t->w);
+ t->w = NULL;
+ }
+
+ if (t->scope) {
+ scf_scope_free(t->scope);
+ t->scope = NULL;
+ }
+
+ free(t);
+ t = NULL;
}
-
- free(t);
- t = NULL;
}
static scf_type_abbrev_t type_abbrevs[] =
--- /dev/null
+int printf(const char* fmt, ...);
+
+void 打印(const char* 信息)
+{
+ printf("%s\n", 信息);
+}
+
+int main()
+{
+ const char* 文本 = "你好, 中文编程!\n";
+
+ 打印(文本);
+ return 0;
+}
#include"scf_lex.h"
-static scf_lex_key_word_t key_words[] = {
+static scf_key_word_t key_words[] =
+{
{"if", SCF_LEX_WORD_KEY_IF},
{"else", SCF_LEX_WORD_KEY_ELSE},
{"struct", SCF_LEX_WORD_KEY_STRUCT},
};
-static scf_lex_escape_char_t escape_chars[] = {
+static scf_escape_char_t escape_chars[] =
+{
{'n', '\n'},
{'r', '\r'},
{'t', '\t'},
{
int i;
for (i = 0; i < sizeof(key_words) / sizeof(key_words[0]); i++) {
- if (!strcmp(key_words[i].text, text)) {
+
+ if (!strcmp(key_words[i].text, text))
return key_words[i].type;
- }
}
+
return -1;
}
{
int i;
for (i = 0; i < sizeof(escape_chars) / sizeof(escape_chars[0]); i++) {
- if (escape_chars[i].origin == c) {
+
+ if (escape_chars[i].origin == c)
return escape_chars[i].escape; // return the escape char
- }
}
// if it isn't in the escape array, return the original char
return c;
}
-scf_lex_error_t* scf_lex_error_alloc(scf_string_t* file, int line, int pos)
-{
- assert(file);
-
- scf_lex_error_t* e = calloc(1, sizeof(scf_lex_error_t));
- assert(e);
-
- e->file = scf_string_clone(file);
- assert(e->file);
-
- e->line = line;
- e->pos = pos;
- return e;
-}
-
-void scf_lex_error_free(scf_lex_error_t* e)
-{
- assert(e);
-
- if (e->message)
- scf_string_free(e->message);
- if (e->file)
- scf_string_free(e->file);
-
- free(e);
- e = NULL;
-}
-
int scf_lex_open(scf_lex_t** plex, const char* path)
{
- printf("%s(),%d, keywords: %ld\n", __func__, __LINE__,
- sizeof(key_words) / sizeof(key_words[0]));
-
- assert(plex);
- assert(path);
+ if (!plex || !path)
+ return -EINVAL;
scf_lex_t* lex = calloc(1, sizeof(scf_lex_t));
- assert(lex);
+ if (!lex)
+ return -ENOMEM;
scf_list_init(&lex->word_list_head);
- scf_list_init(&lex->error_list_head);
- scf_list_init(&lex->char_list_head);
+
+ lex->char_list_head = NULL;
lex->fp = fopen(path, "r");
if (!lex->fp) {
scf_loge("path: %s, errno: %d, pwd: %s\n", path, errno, cwd);
free(lex);
- lex = NULL;
return -1;
}
lex->file = scf_string_cstr(path);
- assert(lex->file);
+ if (!lex->file) {
+ fclose(lex->fp);
+ free(lex);
+ return -ENOMEM;
+ }
lex->nb_lines = 1;
int scf_lex_close(scf_lex_t* lex)
{
- assert(lex);
-
- scf_list_clear(&lex->word_list_head, scf_lex_word_t, list, scf_lex_word_free);
- scf_list_clear(&lex->error_list_head, scf_lex_error_t, list, scf_lex_error_free);
+ if (lex) {
+ scf_list_clear(&lex->word_list_head, scf_lex_word_t, list, scf_lex_word_free);
- free(lex);
- lex = NULL;
+ free(lex);
+ }
return 0;
}
int scf_lex_push_word(scf_lex_t* lex, scf_lex_word_t* word)
{
- assert(lex);
- assert(word);
-
- scf_list_add_front(&lex->word_list_head, &word->list);
+ if (lex && word)
+ scf_list_add_front(&lex->word_list_head, &word->list);
return 0;
}
-static void _lex_space(scf_lex_t* lex)
+static int _lex_plus(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
- scf_lex_char_t* c = _lex_pop_char(lex);
-
- if ('\n' == c->c || '\r' == c->c || '\t' == c->c || ' ' == c->c) {
-
- if ('\n' == c->c) {
- lex->nb_lines++;
- lex->pos = 0;
- } else {
- lex->pos++;
- }
-
- free(c);
- c = NULL;
-
- _lex_space(lex); // recursive call until others, to delete the unexpected space
- } else {
- _lex_push_char(lex, c); // save to the front of temp char list, used it later
- }
-}
+ scf_char_t* c1 = _lex_pop_char(lex);
-static int _lex_plus(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
-{
- scf_lex_char_t* c1 = _lex_pop_char(lex);
if ('+' == c1->c) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
- if ('+' == c2->c) {
- scf_lex_error_t* e = scf_lex_error_alloc(lex->file, lex->nb_lines, lex->pos);
- e->message = scf_string_cstr("error: +++ is not supported");
- scf_list_add_tail(&lex->error_list_head, &e->list);
+ scf_char_t* c2 = _lex_pop_char(lex);
- free(c2);
- free(c1);
- free(c0);
- c2 = NULL;
- c1 = NULL;
- c0 = NULL;
+ if ('+' == c2->c)
+ scf_logw("+++ may cause a BUG in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
- // can add error correction to continue the lexer
- scf_loge("\n");
- return -1;
- } else {
- _lex_push_char(lex, c2);
- c2 = NULL;
+ _lex_push_char(lex, c2);
+ c2 = NULL;
- scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_INC);
- w->text = scf_string_cstr("++");
- lex->pos += 2;
+ scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_INC);
+ w->text = scf_string_cstr("++");
+ lex->pos += 2;
- *pword = w;
+ *pword = w;
+
+ free(c1);
+ c1 = NULL;
- free(c1);
- c1 = NULL;
- }
} else if ('=' == c1->c) {
scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_ADD_ASSIGN);
w->text = scf_string_cstr("+=");
return 0;
}
-static int _lex_minus(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+static int _lex_minus(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
- scf_lex_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c1 = _lex_pop_char(lex);
+
if ('-' == c1->c) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
- if ('-' == c2->c) {
- scf_lex_error_t* e = scf_lex_error_alloc(lex->file, lex->nb_lines, lex->pos);
- e->message = scf_string_cstr("error: --- is not supported");
- scf_list_add_tail(&lex->error_list_head, &e->list);
+ scf_char_t* c2 = _lex_pop_char(lex);
- free(c2);
- free(c1);
- free(c0);
- c2 = NULL;
- c1 = NULL;
- c0 = NULL;
+ if ('-' == c2->c)
+ scf_logw("--- may cause a BUG in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
- // can add error correction to continue the lexer
- scf_loge("\n");
- return -1;
- } else {
- _lex_push_char(lex, c2);
- c2 = NULL;
+ _lex_push_char(lex, c2);
+ c2 = NULL;
- scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DEC);
- w->text = scf_string_cstr("--");
- lex->pos += 2;
+ scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DEC);
+ w->text = scf_string_cstr("--");
+ lex->pos += 2;
+
+ *pword = w;
+ free(c1);
+ c1 = NULL;
- *pword = w;
- free(c1);
- c1 = NULL;
- }
} else if ('>' == c1->c) {
scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_ARROW);
w->text = scf_string_cstr("->");
return 0;
}
-static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
lex->pos++;
if ('0' == c0->c) {
- scf_lex_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c1 = _lex_pop_char(lex);
+
if ('x' == c1->c || 'X' == c1->c) {
// base 16
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
+
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos += 2;
+
free(c1);
- c1 = NULL;
free(c0);
+ c1 = NULL;
c0 = NULL;
return _lex_number_base_16(lex, pword, s);
} else if ('.' == c1->c) {
// double
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
+
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos += 2;
+
free(c1);
- c1 = NULL;
free(c0);
+ c1 = NULL;
c0 = NULL;
while (1) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
+ scf_char_t* c2 = _lex_pop_char(lex);
+
if (c2->c >= '0' && c2->c <= '9') {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
+
free(c2);
c2 = NULL;
+
} else if ('.' == c2->c) {
- // error
- printf("%s(),%d, error: \n", __func__, __LINE__);
+ scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
+
+ free(c2);
+ c2 = NULL;
return -1;
+
} else {
_lex_push_char(lex, c2);
c2 = NULL;
}
}
} else {
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
if (c1->c < '0' || c1->c > '9') {
// is 0
}
} else {
// base 10
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
uint64_t value = c0->c - '0';
int nb_dots = 0;
+ free(c0);
+ c0 = NULL;
+
while (1) {
- scf_lex_char_t* c1 = _lex_pop_char(lex);
-
- if ((c1->c >= '0' && c1->c <= '9') || '.' == c1->c) {
- if ('.' == c1->c) {
- nb_dots++;
- if (nb_dots > 1) {
- // error
- scf_lex_error_t* e = scf_lex_error_alloc(lex->file, lex->nb_lines, lex->pos);
- e->message = scf_string_cstr("error: 2 '.' found, number is wrong");
- scf_list_add_tail(&lex->error_list_head, &e->list);
- printf("%s(),%d, error: \n", __func__, __LINE__);
- return -1;
- }
- } else
- value = value * 10 + c1->c - '0';
+ scf_char_t* c1 = _lex_pop_char(lex);
+
+ if (c1->c >= '0' && c1->c <= '9') {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ value = value * 10 + c1->c - '0';
+
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos++;
+
free(c1);
c1 = NULL;
+
+ } else if ('.' == c1->c) {
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
+ lex->pos++;
+
+ free(c1);
+ c1 = NULL;
+
+ if (++nb_dots > 1) {
+ scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
+ return -1;
+ }
} else {
_lex_push_char(lex, c1);
c1 = NULL;
scf_lex_word_t* w = NULL;
+
if (nb_dots > 0) {
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
w->data.d = atof(s->data);
s = NULL;
*pword = w;
-
- free(c0);
- c0 = NULL;
return 0;
}
}
}
}
-static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
- lex->pos++;
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
+
+ lex->pos += c0->len;
free(c0);
c0 = NULL;
while (1) {
- scf_lex_char_t* c1 = _lex_pop_char(lex);
- if (('a' <= c1->c && 'z' >= c1->c)
- || ('A' <= c1->c && 'Z' >= c1->c)
- || ('0' <= c1->c && '9' >= c1->c)
- || '_' == c1->c
- ) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- lex->pos++;
+ scf_char_t* c1 = _lex_pop_char(lex);
+
+ if ('_' == c1->c
+ || ('a' <= c1->c && 'z' >= c1->c)
+ || ('A' <= c1->c && 'Z' >= c1->c)
+ || ('0' <= c1->c && '9' >= c1->c)
+ || (0x4e00 <= c1->c && 0x9fa5 >= c1->c)) {
+
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
+ lex->pos += c1->len;
+
free(c1);
c1 = NULL;
} else {
return -1;
}
-static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
scf_lex_word_t* w = NULL;
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
- scf_lex_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c1 = _lex_pop_char(lex);
if ('\\' == c1->c) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
- scf_lex_char_t* c3 = _lex_pop_char(lex);
+ scf_char_t* c2 = _lex_pop_char(lex);
+ scf_char_t* c3 = _lex_pop_char(lex);
if ('\'' == c3->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c3->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, c2->len);
+ scf_string_cat_cstr_len(s, c3->utf8, 1);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_CHAR);
w->data.i64 = _find_escape_char(c2->c);
- lex->pos += 4;
+ lex->pos += 3 + c2->len;
free(c3);
- c3 = NULL;
free(c2);
+ c3 = NULL;
c2 = NULL;
} else {
- printf("%s(),%d, error: \n", __func__, __LINE__);
+ scf_loge("const char lost 2nd ' in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
return -1;
}
+
} else {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
+ scf_char_t* c2 = _lex_pop_char(lex);
+
if ('\'' == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_CHAR);
w->data.i64 = c1->c;
- lex->pos += 3;
+ lex->pos += 2 + c1->len;
free(c2);
c2 = NULL;
} else {
- printf("%s(),%d, error: \n", __func__, __LINE__);
+ scf_loge("const char lost 2nd ' in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
return -1;
}
}
*pword = w;
free(c1);
- c1 = NULL;
free(c0);
+ c1 = NULL;
c0 = NULL;
return 0;
}
-static int _lex_string(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+static int _lex_string(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
scf_lex_word_t* w = NULL;
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
- scf_string_t* data = scf_string_alloc();
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, 1);
+ scf_string_t* d = scf_string_alloc();
while (1) {
- scf_lex_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c1 = _lex_pop_char(lex);
+
if ('\"' == c1->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
- w->data.s = data;
- data = NULL;
- w->text = s;
+ w->data.s = d;
+ w->text = s;
+ d = NULL;
s = NULL;
+
lex->pos++;
*pword = w;
free(c1);
c1 = NULL;
return 0;
+
} else if ('\\' == c1->c) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
+ scf_char_t* c2 = _lex_pop_char(lex);
+
int ch2 = _find_escape_char(c2->c);
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
- lex->pos += 2;
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, c2->len);
+ lex->pos += 1 + c2->len;
free(c2);
free(c1);
ch2 <<= 3;
ch2 += c1->c - '0';
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos++;
free(c1);
}
}
- scf_string_cat_cstr_len(data, (char*)&ch2, 1);
+ scf_string_cat_cstr_len(d, (char*)&ch2, 1);
} else
- scf_string_cat_cstr_len(data, (char*)&ch2, 1);
+ scf_string_cat_cstr_len(d, (char*)&ch2, 1);
} else if (EOF == c1->c) {
- printf("%s(),%d, error: \n", __func__, __LINE__);
+ scf_loge("const string lost 2nd \" in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
return -1;
+
} else {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- scf_string_cat_cstr_len(data, (char*)&c1->c, 1);
- lex->pos++;
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
+ scf_string_cat_cstr_len(d, c1->utf8, c1->len);
+ lex->pos += c1->len;
+
free(c1);
c1 = NULL;
}
int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
{
- assert(lex);
- assert(pword);
- assert(lex->fp);
+ if (!lex || !lex->fp || !pword)
+ return -EINVAL;
+
+ scf_list_t* l = NULL;
+ scf_char_t* c = NULL;
+ scf_lex_word_t* w = NULL;
if (!scf_list_empty(&lex->word_list_head)) {
- scf_list_t* l = scf_list_head(&lex->word_list_head);
- scf_lex_word_t* w = scf_list_data(l, scf_lex_word_t, list);
+ l = scf_list_head(&lex->word_list_head);
+ w = scf_list_data(l, scf_lex_word_t, list);
scf_list_del(&w->list);
*pword = w;
return 0;
}
- scf_lex_char_t* c = _lex_pop_char(lex);
- if (EOF == c->c) {
- scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_EOF);
- w->text = scf_string_cstr("eof");
- *pword = w;
- free(c);
- c = NULL;
- return 0;
- }
+ c = _lex_pop_char(lex);
- if ('\n' == c->c || '\r' == c->c || '\t' == c->c || ' ' == c->c) {
-#if 0
- scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_SPACE);
- w->text = scf_string_cstr(" ");
- *pword = w;
-#endif
+ while ('\n' == c->c || '\r' == c->c || '\t' == c->c || ' ' == c->c) {
if ('\n' == c->c) {
lex->nb_lines++;
lex->pos = 0;
- } else {
+ } else
lex->pos++;
- }
+
+ free(c);
+ c = _lex_pop_char(lex);
+ }
+
+ if (EOF == c->c) {
+ w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_EOF);
+ w->text = scf_string_cstr("eof");
+ *pword = w;
free(c);
c = NULL;
- _lex_space(lex);
- return scf_lex_pop_word(lex, pword); // recursive call to drop the SPACE WORD
+ return 0;
}
if ('+' == c->c)
if ('/' == c->c) {
- scf_lex_char_t* c2 = _lex_pop_char(lex);
+ scf_char_t* c2 = _lex_pop_char(lex);
if ('/' == c2->c) {
free(c);
}
if (scf_string_cat(w0->text, w1->text) < 0
- || scf_string_cat(w0->data.s, w1->data.s) < 0) {
+ || scf_string_cat(w0->data.s, w1->data.s) < 0) {
scf_lex_word_free(w1);
scf_lex_word_free(w0);
if ('0' <= c->c && '9' >= c->c)
return _lex_number(lex, pword, c);
- if ('_' == c->c || ('a' <= c->c && 'z' >= c->c) || ('A' <= c->c && 'Z' >= c->c)) {
+ if ('_' == c->c
+ || ('a' <= c->c && 'z' >= c->c)
+ || ('A' <= c->c && 'Z' >= c->c)
+ || (0x4e00 <= c->c && 0x9fa5 >= c->c)) { // support China chars
+
return _lex_identity(lex, pword, c);
}
- scf_loge("c: %c\n", c->c);
+ scf_loge("unknown char: %c, utf: %#x, in file: %s, line: %d\n", c->c, c->c, lex->file->data, lex->nb_lines);
return -1;
}
-
#include"scf_lex_word.h"
-typedef struct {
- char* text;
- int type;
-} scf_lex_key_word_t;
+typedef struct scf_char_s scf_char_t;
typedef struct {
- int origin;
- int escape;
-} scf_lex_escape_char_t;
+ char* text;
+ int type;
+} scf_key_word_t;
typedef struct {
- scf_list_t list; // manage list, all errors here
-
- scf_string_t* message; // error message for user
+ int origin;
+ int escape;
+} scf_escape_char_t;
- scf_string_t* file; // original code file name
- int line; // line in the code file above
- int pos; // position in the line above
+#define SCF_UTF8_MAX 6
+struct scf_char_s
+{
+ scf_char_t* next;
+ int c;
-} scf_lex_error_t;
-
-typedef struct {
- scf_list_t list;
- int c;
-} scf_lex_char_t;
+ int len;
+ uint8_t utf8[SCF_UTF8_MAX];
+};
typedef struct {
- scf_list_t word_list_head; // word list head
- scf_list_t error_list_head; // error list head
+ scf_list_t word_list_head; // word list head
+ scf_char_t* char_list_head; // temp char list head
- scf_list_t char_list_head; // temp char list head
- FILE* fp; // file pointer to the code
+ FILE* fp; // file pointer to the code
- int nb_identities;
-
- scf_string_t* file; // original code file name
- int nb_lines;
- int pos;
+ int nb_identities;
+ scf_string_t* file; // original code file name
+ int nb_lines;
+ int pos;
} scf_lex_t;
-scf_lex_error_t* scf_lex_error_alloc(scf_string_t* file, int line, int pos);
-void scf_lex_error_free(scf_lex_error_t* e);
-scf_lex_char_t* _lex_pop_char (scf_lex_t* lex);
-void _lex_push_char(scf_lex_t* lex, scf_lex_char_t* c);
+scf_char_t* _lex_pop_char (scf_lex_t* lex);
+void _lex_push_char(scf_lex_t* lex, scf_char_t* c);
-int scf_lex_open(scf_lex_t** plex, const char* path);
-int scf_lex_close(scf_lex_t* lex);
+int scf_lex_open (scf_lex_t** plex, const char* path);
+int scf_lex_close(scf_lex_t* lex);
-int scf_lex_push_word(scf_lex_t* lex, scf_lex_word_t* word);
-int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword);
+int scf_lex_push_word(scf_lex_t* lex, scf_lex_word_t* word);
+int scf_lex_pop_word (scf_lex_t* lex, scf_lex_word_t** pword);
int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s);
int _lex_number_base_8 (scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s);
int _lex_number_base_2 (scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s);
-int _lex_dot (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0);
+int _lex_dot (scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0);
-int _lex_op1_ll1 (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0);
-int _lex_op2_ll1 (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0, char* chs, int* types, int n);
-int _lex_op3_ll1 (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3);
-#endif
+int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int type0);
+int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int type0, char* chs, int* types, int n);
+int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3);
+#endif
#include"scf_lex.h"
-scf_lex_char_t* _lex_pop_char(scf_lex_t* lex)
+scf_char_t* _lex_pop_char(scf_lex_t* lex)
{
assert(lex);
assert(lex->fp);
- if (!scf_list_empty(&lex->char_list_head)) {
- scf_list_t* l = scf_list_head(&lex->char_list_head);
- scf_lex_char_t* c = scf_list_data(l, scf_lex_char_t, list);
- scf_list_del(&c->list);
+ scf_char_t* c;
+
+ if (lex->char_list_head) {
+ c = lex->char_list_head;
+ lex->char_list_head = c->next;
return c;
}
- scf_lex_char_t* c = malloc(sizeof(scf_lex_char_t));
- assert(c);
+ c = malloc(sizeof(scf_char_t));
+ if (!c)
+ return NULL;
+
+ int ret = fgetc(lex->fp);
+ if (EOF == ret) {
+ c->c = ret;
+ return c;
+ }
+
+ if (ret < 0x80) {
+ c->c = ret;
+ c->len = 1;
+ c->utf8[0] = ret;
+ return c;
+ }
+
+ if (0x6 == (ret >> 5)) {
+ c->c = ret & 0x1f;
+ c->len = 2;
+
+ } else if (0xe == (ret >> 4)) {
+ c->c = ret & 0xf;
+ c->len = 3;
+
+ } else if (0x1e == (ret >> 3)) {
+ c->c = ret & 0x7;
+ c->len = 4;
+
+ } else if (0x3e == (ret >> 2)) {
+ c->c = ret & 0x3;
+ c->len = 5;
+
+ } else if (0x7e == (ret >> 1)) {
+ c->c = ret & 0x1;
+ c->len = 6;
+ } else {
+ scf_loge("utf8 first byte wrong %#x, file: %s, line: %d\n", ret, lex->file->data, lex->nb_lines);
+ free(c);
+ return NULL;
+ }
+
+ c->utf8[0] = ret;
+
+ int i;
+ for (i = 1; i < c->len; i++) {
+
+ ret = fgetc(lex->fp);
+
+ if (0x2 == (ret >> 6)) {
+ c->c <<= 6;
+ c->c |= ret & 0x3f;
+
+ c->utf8[i] = ret;
+ } else {
+ scf_loge("utf8 byte[%d] wrong %#x, file: %s, line: %d\n", i + 1, ret, lex->file->data, lex->nb_lines);
+ free(c);
+ return NULL;
+ }
+ }
- c->c = fgetc(lex->fp);
return c;
}
-void _lex_push_char(scf_lex_t* lex, scf_lex_char_t* c)
+void _lex_push_char(scf_lex_t* lex, scf_char_t* c)
{
assert(lex);
assert(c);
- scf_list_add_front(&lex->char_list_head, &c->list);
+ c->next = lex->char_list_head;
+ lex->char_list_head = c;
}
-int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0)
+int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int type0)
{
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
- lex->pos++;
+ lex->pos += c0->len;
w->text = s;
s = NULL;
return 0;
}
-int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
+int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0,
int type0, char* chs, int* types, int n)
{
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
scf_lex_word_t* w = NULL;
- scf_lex_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c1 = _lex_pop_char(lex);
int i;
for (i = 0; i < n; i++) {
}
if (i < n) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, types[i]);
- lex->pos += 2;
+ lex->pos += c0->len + c1->len;
free(c1);
c1 = NULL;
_lex_push_char(lex, c1);
c1 = NULL;
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
- lex->pos++;
+ lex->pos += c0->len;
}
w->text = s;
return 0;
}
-int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
+int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0,
char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3)
{
- scf_lex_char_t* c1 = _lex_pop_char(lex);
- scf_lex_char_t* c2 = NULL;
+ scf_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c2 = NULL;
scf_lex_word_t* w = NULL;
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
if (ch1_0 == c1->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
c2 = _lex_pop_char(lex);
if (ch2 == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, c2->len);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
w->text = s;
s = NULL;
- lex->pos += 3;
+ lex->pos += c0->len + c1->len + c2->len;
free(c2);
c2 = NULL;
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type1);
w->text = s;
s = NULL;
- lex->pos += 2;
+ lex->pos += c0->len + c1->len;
}
free(c1);
c1 = NULL;
} else if (ch1_1 == c1->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, c1->len);
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type2);
w->text = s;
s = NULL;
- lex->pos += 2;
+ lex->pos += c0->len + c1->len;
free(c1);
c1 = NULL;
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type3);
w->text = s;
s = NULL;
- lex->pos++;
+ lex->pos += c0->len;
}
free(c0);
int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
{
- scf_lex_char_t* c2;
- scf_lex_char_t* c3;
+ scf_char_t* c2;
+ scf_char_t* c3;
scf_lex_word_t* w;
int dot = 0;
break;
}
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
free(c2);
int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
{
- scf_lex_char_t* c2;
+ scf_char_t* c2;
scf_lex_word_t* w;
uint64_t value = 0;
value2 = c2->c - 'A' + 10;
else if ('_' == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
free(c2);
value <<= 4;
value += value2;
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
free(c2);
int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
{
- scf_lex_char_t* c2;
+ scf_char_t* c2;
scf_lex_word_t* w;
uint64_t value = 0;
c2 = _lex_pop_char(lex);
if (c2->c >= '0' && c2->c <= '7') {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
value = (value << 3) + c2->c - '0';
return -1;
} else if ('_' == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
free(c2);
int _lex_number_base_2(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
{
- scf_lex_char_t* c2;
+ scf_char_t* c2;
scf_lex_word_t* w;
uint64_t value = 0;
c2 = _lex_pop_char(lex);
if (c2->c >= '0' && c2->c <= '1') {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
value = (value << 1) + c2->c - '0';
return -1;
} else if ('_' == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos++;
free(c2);
}
}
-int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
{
- scf_lex_char_t* c1 = _lex_pop_char(lex);
- scf_lex_char_t* c2 = NULL;
+ scf_char_t* c1 = _lex_pop_char(lex);
+ scf_char_t* c2 = NULL;
scf_lex_word_t* w = NULL;
- scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
+ scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
- lex->pos++;
+ lex->pos += c0->len;
free(c0);
c0 = NULL;
if ('.' == c1->c) {
+ assert(1 == c1->len);
c2 = _lex_pop_char(lex);
if ('.' == c2->c) {
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
- scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+ assert(1 == c2->len);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
+ scf_string_cat_cstr_len(s, c2->utf8, 1);
lex->pos += 2;
free(c1);
_lex_push_char(lex, c2);
c2 = NULL;
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos++;
free(c1);
break;
}
- scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+ scf_string_cat_cstr_len(s, c1->utf8, 1);
lex->pos++;
free(c1);
}
if (numbers > 0) {
-
if (dots > 1) {
scf_loge("\n");
return -1;
c->uf = ed->uf;
c->uh = ed->uh;
c->ops = ed->ops;
-
- if (ed->cpk) {
- c->n_cpk = strlen(ed->cpk) + 1;
-
- c->cpk = strdup(ed->cpk);
- if (!c->cpk) {
- ScfEcomponent_free(c);
- return NULL;
- }
- }
}
int i;
return NULL;
}
- pin->id = i;
+ pin->id = i;
+ pin->ic_lid = -1;
+
+ scf_loge("pin %p, id: %ld, ic_lid: %ld\n", pin, pin->id, pin->ic_lid);
if (scf_ecomponent__add_pin(c, pin) < 0) {
ScfEcomponent_free(c);
return -EINVAL;
}
+
+static int epin_cmp(const void* v0, const void* v1)
+{
+ const uint64_t* t0 = v0;
+ const uint64_t* t1 = v1;
+
+ if (t0[0] < t1[0])
+ return -1;
+
+ if (t0[0] > t1[0])
+ return 1;
+
+ if (t0[1] < t1[1])
+ return -1;
+
+ if (t0[1] > t1[1])
+ return 1;
+ return 0;
+}
+
+int scf_pins_same_line(ScfEfunction* f)
+{
+ ScfEcomponent* c;
+ ScfEline* el;
+ ScfEline* el2;
+ ScfEpin* p;
+ ScfEpin* p2;
+
+ long i;
+ long j;
+ long k;
+ long m;
+ long n;
+
+ for (i = 0; i < f->n_components; i++) {
+ c = f->components[i];
+
+ for (j = 0; j < c->n_pins; j++) {
+ p = c->pins[j];
+
+ qsort(p->tos, p->n_tos / 2, sizeof(uint64_t) * 2, epin_cmp);
+
+ for (k = 0; k < f->n_elines; k++) {
+ el = f->elines[k];
+
+ for (m = 0; m + 1 < el->n_pins; m += 2) {
+
+ if (el->pins[m] == p->cid && el->pins[m + 1] == p->id)
+ goto next;
+ }
+
+ m = 0;
+ n = 0;
+ while (m + 1 < el->n_pins && n + 1 < p->n_tos) {
+
+ if (el->pins[m] < p->tos[n])
+ m += 2;
+ else if (el->pins[m] > p->tos[n])
+ n += 2;
+
+ else if (el->pins[m + 1] < p->tos[n + 1])
+ m += 2;
+ else if (el->pins[m + 1] > p->tos[n + 1])
+ n += 2;
+
+ else {
+ if (scf_eline__add_pin(el, p->cid, p->id) < 0)
+ return -ENOMEM;
+
+ p ->lid = el->id;
+ p ->c_lid = el->id;
+ el->flags |= p->flags;
+ goto next;
+ }
+ }
+ }
+
+ el = scf_eline__alloc();
+ if (!el)
+ return -ENOMEM;
+ el->id = f->n_elines;
+
+ if (scf_efunction__add_eline(f, el) < 0) {
+ ScfEline_free(el);
+ return -ENOMEM;
+ }
+
+ if (scf_eline__add_pin(el, p->cid, p->id) < 0)
+ return -ENOMEM;
+
+ p ->lid = el->id;
+ p ->c_lid = el->id;
+ el->flags |= p->flags;
+next:
+ for (n = 0; n + 1 < p->n_tos; n += 2) {
+
+ p2 = f->components[p->tos[n]]->pins[p->tos[n + 1]];
+
+ if (p2->cid > p->cid
+ || (p2->cid == p->cid && p2->id > p->id))
+ break;
+
+ el2 = f->elines[p2->lid];
+
+ if (el2 == el)
+ continue;
+
+ if (el2->id < el->id)
+ SCF_XCHG(el2, el);
+
+ for (m = 0; m + 1 < el2->n_pins; m += 2) {
+ p2 = f->components[el2->pins[m]]->pins[el2->pins[m + 1]];
+
+ if (scf_eline__add_pin(el, p2->cid, p2->id) < 0)
+ return -ENOMEM;
+
+ p2->lid = el->id;
+ p2->c_lid = el->id;
+ el->flags |= p2->flags;
+ }
+
+ qsort(el->pins, el->n_pins / 2, sizeof(uint64_t) * 2, epin_cmp);
+
+ el2->n_pins = 0;
+ }
+ p = NULL;
+ }
+ }
+
+ for (i = 0; i < f->n_elines; ) {
+ el = f->elines[i];
+
+ if (0 == el->n_pins) {
+ scf_efunction__del_eline(f, el);
+ ScfEline_free(el);
+ continue;
+ }
+
+ el->c_pins = el->n_pins;
+ i++;
+ }
+
+ for (i = 0; i < f->n_elines; ) {
+ el = f->elines[i];
+ el->id = i;
+
+ int64_t eid = -1;
+
+ for (j = 0; j + 1 < el->n_pins; j += 2) {
+
+ c = f->components[el->pins[j]];
+ p = c->pins [el->pins[j + 1]];
+
+ p->lid = i;
+ p->c_lid = i;
+
+ if (p->ic_lid < 0)
+ continue;
+
+ if (eid < 0)
+ eid = p->ic_lid;
+
+ else if (eid != p->ic_lid) {
+ scf_loge("IC pin number set error, prev: %ld, current: %ld\n", eid, p->ic_lid);
+ return -EINVAL;
+ }
+
+ scf_logd("pin j: %ld, c%ldp%ld\n", j, el->pins[j], el->pins[j + 1]);
+ }
+
+ if (eid >= f->n_elines) {
+ scf_loge("IC pin number set error, max: %ld, current: %ld\n", f->n_elines - 1, eid);
+ return -EINVAL;
+ }
+
+ scf_logd("i: %ld, eid: %ld\n", i, eid);
+
+ if (eid >= 0 && eid != i) {
+ el->id = eid;
+
+ for (j = 0; j + 1 < el->n_pins; j += 2) {
+
+ c = f->components[el->pins[j]];
+ p = c->pins [el->pins[j + 1]];
+
+ p->lid = eid;
+ p->c_lid = eid;
+ }
+
+ SCF_XCHG(f->elines[eid], f->elines[i]);
+ continue;
+ }
+
+ i++;
+ }
+
+ return 0;
+}
SCF_PACK_DEF_VARS(uint64_t, tos);
SCF_PACK_DEF_VAR(uint64_t, c_lid);
+ SCF_PACK_DEF_VAR(int64_t, ic_lid);
SCF_PACK_DEF_OBJ(ScfEcomponent, IC);
SCF_PACK_DEF_VAR(double, v);
SCF_PACK_INFO_VARS(ScfEpin, tos, uint64_t),
SCF_PACK_INFO_VAR(ScfEpin, c_lid),
+SCF_PACK_INFO_VAR(ScfEpin, ic_lid),
+
SCF_PACK_INFO_VAR(ScfEpin, v),
SCF_PACK_INFO_VAR(ScfEpin, a),
SCF_PACK_DEF_VAR(uint64_t, model);
SCF_PACK_DEF_OBJS(ScfEpin, pins);
- SCF_PACK_DEF_VARS(uint8_t, cpk);
+ SCF_PACK_DEF_OBJ(ScfEfunction, pf);
SCF_PACK_DEF_OBJ(ScfEfunction, f);
SCF_PACK_DEF_OBJ(ScfEops, ops);
SCF_PACK_INFO_VAR(ScfEcomponent, model),
SCF_PACK_INFO_OBJS(ScfEcomponent, pins, ScfEpin),
-SCF_PACK_INFO_VARS(ScfEcomponent, cpk, uint8_t),
-
SCF_PACK_INFO_VAR(ScfEcomponent, v),
SCF_PACK_INFO_VAR(ScfEcomponent, a),
int scf_eboard__add_function(ScfEboard* b, ScfEfunction* f);
int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f);
+int scf_pins_same_line(ScfEfunction* f);
+
#define EDA_INST_ADD_COMPONENT(_ef, _c, _type) \
do { \
_c = scf_ecomponent__alloc(_type); \
printf("%s(),%d, main ok\n", __func__, __LINE__);
return 0;
}
-
.init_module = _dfa_init_module_identity,
.init_syntax = _dfa_init_syntax_identity,
};
-
.init_module = _dfa_init_module_type,
.init_syntax = _dfa_init_syntax_type,
};
-
.init_module = _dfa_init_module_var,
.init_syntax = _dfa_init_syntax_var,
};
-
return NULL;
}
-int scf_const_opt(scf_ast_t* ast)
-{
- scf_handler_data_t d = {0};
-
- int ret = _scf_expr_calculate_internal(ast, (scf_node_t*)ast->root_block, &d);
-
- if (ret < 0) {
- scf_loge("\n");
- return -1;
- }
-
- return 0;
-}
-
int scf_function_const_opt(scf_ast_t* ast, scf_function_t* f)
{
scf_handler_data_t d = {0};
int scf_function_const_opt(scf_ast_t* ast, scf_function_t* f);
-int scf_const_opt(scf_ast_t* ast);
-
#endif
-
int scf_parse_open(scf_parse_t** pparse)
{
- assert(pparse);
+ if (!pparse)
+ return -EINVAL;
scf_parse_t* parse = calloc(1, sizeof(scf_parse_t));
- assert(parse);
+ if (!parse)
+ return -EINVAL;
if (scf_ast_open(&parse->ast) < 0) {
scf_loge("\n");
return -1;
}
+int scf_parse_close(scf_parse_t* parse)
+{
+ if (parse) {
+ free(parse);
+ parse = NULL;
+ }
+
+ return 0;
+}
+
static int _find_sym(const void* v0, const void* v1)
{
const char* name = v0;
return 0;
}
-int scf_parse_close(scf_parse_t* parse)
-{
- assert(parse);
-
- free(parse);
- parse = NULL;
- return 0;
-}
-
int scf_parse_file(scf_parse_t* parse, const char* path)
{
assert(parse);
return -1;
}
- scf_operator_t* op_index = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
- scf_type_t* t_int = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
- scf_node_t* node_root = *pnode;
+ scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
+ scf_node_t* root = *pnode;
- if (!node_root) {
- node_root = scf_node_alloc(NULL, array->type, array);
- }
+ if (!root)
+ root = scf_node_alloc(NULL, array->type, array);
scf_logi("array->nb_dimentions: %d, nb_indexes: %d\n", array->nb_dimentions, nb_indexes);
return -1;
}
- scf_variable_t* v_index = scf_variable_alloc(NULL, t_int);
+ scf_variable_t* v_index = scf_variable_alloc(NULL, t);
v_index->const_flag = 1;
v_index->const_literal_flag = 1;
v_index->data.i = k;
scf_node_t* node_index = scf_node_alloc(NULL, v_index->type, v_index);
- scf_node_t* node_op_index = scf_node_alloc(w, op_index->type, NULL);
+ scf_node_t* node_op_index = scf_node_alloc(w, SCF_OP_ARRAY_INDEX, NULL);
- scf_node_add_child(node_op_index, node_root);
+ scf_node_add_child(node_op_index, root);
scf_node_add_child(node_op_index, node_index);
- node_root = node_op_index;
+ root = node_op_index;
}
- *pnode = node_root;
+ *pnode = root;
return array->nb_dimentions;
}
return -1;
}
- scf_type_t* t = scf_block_find_type_type(ast->current_block, _struct->type);
- scf_variable_t* v = NULL;
-
- scf_operator_t* op_pointer = scf_find_base_operator_by_type(SCF_OP_POINTER);
-// scf_type_t* t_int = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
- scf_node_t* node_root = *pnode;
+ scf_type_t* t = scf_block_find_type_type(ast->current_block, _struct->type);
+ scf_variable_t* v = NULL;
+ scf_node_t* root = *pnode;
- if (!node_root) {
- node_root = scf_node_alloc(NULL, _struct->type, _struct);
- }
+ if (!root)
+ root = scf_node_alloc(NULL, _struct->type, _struct);
int j = 0;
while (j < nb_indexes) {
v = t->scope->vars->data[k];
- scf_node_t* node_op_pointer = scf_node_alloc(w, op_pointer->type, NULL);
- scf_node_t* node_v = scf_node_alloc(NULL, v->type, v);
+ scf_node_t* node_op_pointer = scf_node_alloc(w, SCF_OP_POINTER, NULL);
+ scf_node_t* node_v = scf_node_alloc(NULL, v->type, v);
- scf_node_add_child(node_op_pointer, node_root);
+ scf_node_add_child(node_op_pointer, root);
scf_node_add_child(node_op_pointer, node_v);
- node_root = node_op_pointer;
+ root = node_op_pointer;
scf_logi("j: %d, k: %d, v: '%s'\n", j, k, v->w->text->data);
j++;
if (v->nb_dimentions > 0) {
- int ret = _scf_array_member_init(ast, w, v, indexes + j, nb_indexes - j, &node_root);
+ int ret = _scf_array_member_init(ast, w, v, indexes + j, nb_indexes - j, &root);
if (ret < 0) {
scf_loge("\n");
return -1;
scf_logi("struct var member: %s->%s\n", _struct->w->text->data, v->w->text->data);
- *pnode = node_root;
+ *pnode = root;
return nb_indexes;
}
if (!type_v) {
type_v = scf_block_find_type_type(ast->current_block, v->type);
+
if (!type_v) {
scf_loge("\n");
return -1;
int scf_array_member_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* array, intptr_t* indexes, int nb_indexes, scf_node_t** pnode)
{
- scf_operator_t* op_index = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
- scf_type_t* t_int = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
+ scf_node_t* root = NULL;
- scf_node_t* node_root = NULL;
-
- int ret = _scf_array_member_init(ast, w, array, indexes, nb_indexes, &node_root);
+ int ret = _scf_array_member_init(ast, w, array, indexes, nb_indexes, &root);
if (ret < 0) {
scf_loge("\n");
return -1;
return -1;
}
- *pnode = node_root;
+ *pnode = root;
return nb_indexes;
}
- ret = scf_struct_member_init(ast, w, array, indexes + ret, nb_indexes - ret, &node_root);
+ ret = scf_struct_member_init(ast, w, array, indexes + ret, nb_indexes - ret, &root);
if (ret < 0) {
scf_loge("\n");
return -1;
}
- *pnode = node_root;
+ *pnode = root;
return nb_indexes;
}
int scf_array_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs)
{
- int nb_unset_dims = 0;
+ dfa_init_expr_t* init_expr;
+
+ int nb_unset_dims = 0;
int unset_dims[8];
int i;
+ int j;
for (i = 0; i < var->nb_dimentions; i++) {
assert(var->dimentions);
if (nb_unset_dims > 1) {
scf_loge("\n");
return -1;
- } else if (1 == nb_unset_dims) {
+ }
+
+ if (1 == nb_unset_dims) {
int unset_dim = unset_dims[0];
int unset_index_max = -1;
for (i = 0; i < init_exprs->size; i++) {
-
- dfa_init_expr_t* init_expr = init_exprs->data[i];
+ init_expr = init_exprs->data[i];
if ((intptr_t)init_expr->current_index->data[unset_dim] > unset_index_max)
unset_index_max = (intptr_t)init_expr->current_index->data[unset_dim];
-
}
var->dimentions[unset_dim] = unset_index_max + 1;
}
for (i = 0; i < init_exprs->size; i++) {
+ init_expr = init_exprs->data[i];
- dfa_init_expr_t* init_expr = init_exprs->data[i];
-
- int j;
for (j = 0; j < var->nb_dimentions; j++) {
printf("\033[32m%s(), %d, i: %d, dim: %d, size: %d, index: %d\033[0m\n",
scf_loge("index [%d] out of size [%d], in dim: %d\n",
(int)(intptr_t)init_expr->current_index->data[j], var->dimentions[j], j);
-
return -1;
}
}
}
- scf_type_t* t = scf_block_find_type_type(ast->current_block,SCF_VAR_INT);
- scf_operator_t* op_index = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
- scf_operator_t* op_assign = scf_find_base_operator_by_type(SCF_OP_ASSIGN);
-
for (i = 0; i < init_exprs->size; i++) {
+ init_expr = init_exprs->data[i];
- dfa_init_expr_t* init_expr = init_exprs->data[i];
scf_logi("#### data init, i: %d, init_expr->expr: %p\n", i, init_expr->expr);
scf_expr_t* e = scf_expr_alloc();
- scf_node_t* node_assign = scf_node_alloc(w, op_assign->type, NULL);
+ scf_node_t* assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
scf_node_t* node = NULL;
intptr_t* indexes = (intptr_t*)init_expr->current_index->data;
- int nb_indexes = init_expr->current_index->size;
+ int nb_indexes = init_expr->current_index->size;
if (scf_array_member_init(ast, w, var, indexes, nb_indexes, &node) < 0) {
scf_loge("\n");
return -1;
}
- scf_node_add_child(node_assign, node);
- scf_node_add_child(node_assign, init_expr->expr);
- scf_expr_add_node(e, node_assign);
-// scf_node_add_child((scf_node_t*)ast->current_block, e);
+ scf_node_add_child(assign, node);
+ scf_node_add_child(assign, init_expr->expr);
+ scf_expr_add_node(e, assign);
scf_vector_free(init_expr->current_index);
init_expr->current_index = NULL;
return 0;
}
-
int scf_struct_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs)
{
- scf_type_t* t = scf_block_find_type_type(ast->current_block,SCF_VAR_INT);
- scf_operator_t* op_index = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
- scf_operator_t* op_assign = scf_find_base_operator_by_type(SCF_OP_ASSIGN);
+ dfa_init_expr_t* init_expr;
int i;
for (i = 0; i < init_exprs->size; i++) {
+ init_expr = init_exprs->data[i];
- dfa_init_expr_t* init_expr = init_exprs->data[i];
scf_logi("#### struct init, i: %d, init_expr->expr: %p\n", i, init_expr->expr);
scf_node_t* node = NULL;
intptr_t* indexes = (intptr_t*)init_expr->current_index->data;
- int nb_indexes = init_expr->current_index->size;
+ int nb_indexes = init_expr->current_index->size;
if (scf_struct_member_init(ast, w, var, indexes, nb_indexes, &node) < 0) {
scf_loge("\n");
return -1;
}
- scf_expr_t* e = scf_expr_alloc();
- scf_node_t* node_assign = scf_node_alloc(w, op_assign->type, NULL);
+ scf_expr_t* e = scf_expr_alloc();
+ scf_node_t* assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
- scf_node_add_child(node_assign, node);
- scf_node_add_child(node_assign, init_expr->expr);
- scf_expr_add_node(e, node_assign);
+ scf_node_add_child(assign, node);
+ scf_node_add_child(assign, init_expr->expr);
+ scf_expr_add_node(e, assign);
scf_vector_free(init_expr->current_index);
init_expr->current_index = NULL;
scf_string_t* scf_string_alloc()
{
scf_string_t* s = malloc(sizeof(scf_string_t));
- if (!s) {
+ if (!s)
return NULL;
- }
s->data = malloc(SCF_STRING_NUMBER_INC + 1);
if (!s->data) {
return s;
}
-scf_string_t* scf_string_clone(scf_string_t* s)
+scf_string_t* scf_string_clone(scf_string_t* s)
{
- if (!s) {
+ if (!s)
return NULL;
- }
scf_string_t* s1 = malloc(sizeof(scf_string_t));
- if (!s1) {
+ if (!s1)
return NULL;
- }
- if (s->capacity > 0) {
+ if (s->capacity > 0)
s1->capacity = s->capacity;
- } else if (s->len > 0) {
+ else if (s->len > 0)
s1->capacity = s->len;
- } else {
+ else
s1->capacity = SCF_STRING_NUMBER_INC;
- }
s1->data = malloc(s1->capacity + 1);
if (!s1->data) {
}
s1->len = s->len;
- if (s->len > 0) {
+ if (s->len > 0)
memcpy(s1->data, s->data, s->len);
- }
- s1->data[s1->len] = '\0';
+ s1->data[s1->len] = '\0';
return s1;
}
-scf_string_t* scf_string_cstr(const char* str)
+scf_string_t* scf_string_cstr(const char* str)
{
- if (!str) {
+ if (!str)
return NULL;
- }
return scf_string_cstr_len(str, strlen(str));
}
-scf_string_t* scf_string_cstr_len(const char* str, size_t len)
+scf_string_t* scf_string_cstr_len(const char* str, size_t len)
{
- if (!str) {
+ if (!str)
return NULL;
- }
scf_string_t s;
s.capacity = -1;
void scf_string_free(scf_string_t* s)
{
- if (!s) {
+ if (!s)
return;
- }
- if (s->capacity > 0) {
+ if (s->capacity > 0)
free(s->data);
- }
free(s);
s = NULL;
if (!s0 || !s1 || !s0->data || !s1->data)
return -EINVAL;
- if (s0->len < s1->len) {
+ if (s0->len < s1->len)
return -1;
- } else if (s0->len > s1->len) {
+
+ if (s0->len > s1->len)
return 1;
- } else {
- return strncmp(s0->data, s1->data, s0->len);
- }
+ return strncmp(s0->data, s1->data, s0->len);
}
int scf_string_cmp_cstr(const scf_string_t* s0, const char* str)
int scf_string_cat(scf_string_t* s0, const scf_string_t* s1)
{
- if (!s0 || !s1 || !s0->data || !s1->data) {
- scf_loge("\n");
+ if (!s0 || !s1 || !s0->data || !s1->data)
return -EINVAL;
- }
assert(s0->capacity > 0);
if (s0->len + s1->len > s0->capacity) {
char* p = realloc(s0->data, s0->len + s1->len + SCF_STRING_NUMBER_INC + 1);
- if (!p) {
- scf_loge("\n");
+ if (!p)
return -ENOMEM;
- }
s0->data = p;
s0->capacity = s0->len + s1->len + SCF_STRING_NUMBER_INC;
int scf_string_cat_cstr_len(scf_string_t* s0, const char* str, size_t len)
{
- if (!s0 || !s0->data || !str) {
- scf_loge("\n");
+ if (!s0 || !s0->data || !str)
return -EINVAL;
- }
scf_string_t s1;
s1.capacity = -1;
int ret;
if (0 == str->len) {
-
if (scf_string_cat_cstr_len(str, data, len) < 0)
return -1;
return 0;