summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/aplwc_internal.h3
-rw-r--r--src/lib/main.c2
-rw-r--r--src/lib/module.c46
-rw-r--r--src/lib/syntax.c48
4 files changed, 63 insertions, 36 deletions
diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h
index c123d63..ca7e719 100644
--- a/src/lib/aplwc_internal.h
+++ b/src/lib/aplwc_internal.h
@@ -171,7 +171,7 @@ struct string *substring(struct aplwc *, struct string *, size_t, size_t);
/* syntax.c */
struct token_list *scan_string(struct aplwc *, struct string *, int);
-enum aplwc_rc check_tokens(struct aplwc_module *, struct token_list *);
+enum aplwc_rc check_tokens(struct aplwc *, struct aplwc_module *, struct token_list *);
enum aplwc_rc keyword_init(struct aplwc *);
/* symtab.c */
@@ -179,6 +179,7 @@ enum aplwc_rc getsym(struct aplwc *, struct string *, symbol_t *);
/* module.c */
enum aplwc_rc load_module(struct aplwc *, struct string *, struct token_list *);
+struct aplwc_module *module_lookup(struct aplwc *, struct string *);
/* unicode.c */
int is_id_start(uint32_t);
diff --git a/src/lib/main.c b/src/lib/main.c
index 6cfff40..e182a9e 100644
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -131,7 +131,7 @@ aplwc_read(struct aplwc *aplwc, const char *linestr, AplwcLine *lineptr)
goto end;
MEMPTR(1, tokens);
- if((aplwc->last_error = check_tokens(NULL, tokens)) != APLWC_OK)
+ if((aplwc->last_error = check_tokens(aplwc, NULL, tokens)) != APLWC_OK)
goto end;
if((line = memory_alloc_aplwc_line(aplwc)) == NULL)
diff --git a/src/lib/module.c b/src/lib/module.c
index aaa9634..9c2cbc2 100644
--- a/src/lib/module.c
+++ b/src/lib/module.c
@@ -72,20 +72,20 @@ read_keyword_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offse
switch(t(0).data.keyword){
case KW_MODULE:
if((max < 1) || (t(1).tag != TOKEN_TAG_IDENTIFIER))
- goto fail;
+ goto fail_syntax;
len = 1;
break;
case KW_SYMBOL:
if((max < 1) || (t(1).tag != TOKEN_TAG_IDENTIFIER))
- goto fail;
+ goto fail_syntax;
if((max < 2) || (t(2).tag != TOKEN_TAG_UNKNOWN_SYM))
- goto fail;
+ goto fail_syntax;
len = 2;
if((m = add_member(aplwc, module, t(1).data.symbol, NULL, 0)) == NULL)
- goto fail;
+ goto fail_other;
if(add_member(aplwc, module, t(2).data.symbol, m, 0) == NULL)
- goto fail;
+ goto fail_other;
break;
case KW_EXPORT:
for(len = 1; (size_t)len < max; len++){
@@ -93,12 +93,14 @@ read_keyword_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offse
case TOKEN_TAG_UNKNOWN_SYM:
case TOKEN_TAG_IDENTIFIER:
if(add_member(aplwc, module, t(len).data.symbol, NULL, 1) == NULL)
- goto fail;
+ goto fail_other;
break;
case TOKEN_TAG_NEWLINE:
goto end;
default:
-fail:
+fail_syntax:
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+fail_other:
len = -1;
goto end;
}
@@ -108,7 +110,7 @@ fail:
if(ALWAYS(len >= 0) && (max > (size_t)len))
if(t(len+1).tag != TOKEN_TAG_NEWLINE)
- goto fail;
+ goto fail_syntax;
len++; /* For the keyword itself */
end:
MEMPTRS_EXIT(aplwc);
@@ -117,7 +119,7 @@ end:
}
static int
-read_function_decl(struct aplwc_module *module, size_t offset)
+read_function_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offset)
{
int len, ok;
@@ -128,7 +130,11 @@ read_function_decl(struct aplwc_module *module, size_t offset)
break;
}
}
- return ok ? len : -1;
+ if(!ok){
+ len = -1;
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+ }
+ return len;
}
static int
@@ -141,8 +147,9 @@ read_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offset)
case TOKEN_TAG_KEYWORD:
return read_keyword_decl(aplwc, module, offset);
case TOKEN_TAG_DEL:
- return read_function_decl(module, offset);
+ return read_function_decl(aplwc, module, offset);
default:
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
return -1;
}
}
@@ -152,27 +159,23 @@ read_decls(struct aplwc *aplwc, struct aplwc_module *module)
{
size_t offset;
int skip;
- enum aplwc_rc rc;
MEMPTRS(aplwc, 1);
MEMPTR(0, module);
- rc = APLWC_OK;
for(offset = 0; offset < module->tokens->length; offset++){
skip = read_decl(aplwc, module, offset);
- if(skip == -1){
- rc = APLWC_INVALID_SYNTAX;
+ if(skip == -1)
goto end;
- }
offset += skip;
}
end:
MEMPTRS_EXIT(aplwc);
- return rc;
+ return aplwc->last_error;
}
-static struct aplwc_module *
+struct aplwc_module *
module_lookup(struct aplwc *aplwc, struct string *name)
{
struct aplwc_module *m;
@@ -193,7 +196,7 @@ resolve_imports(struct aplwc *aplwc, struct aplwc_module *module)
struct module_member *m;
enum aplwc_rc rc;
- MEMPTRS(aplwc, 1);
+ MEMPTRS(aplwc, 3);
MEMPTR(0, module);
rc = APLWC_OK;
@@ -204,6 +207,9 @@ resolve_imports(struct aplwc *aplwc, struct aplwc_module *module)
if((imported = module_lookup(aplwc, name)) == NULL)
goto end; /* only because it is Boot for now... */
+ MEMPTR(1, imported);
+ m = NULL;
+ MEMPTR(2, m);
for(m = imported->members; m; m = m->link){
if(m->exported == 0)
@@ -244,7 +250,7 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens)
if((aplwc->last_error = resolve_imports(aplwc, module)) != APLWC_OK)
goto end;
- if((aplwc->last_error = check_tokens(module, tokens)) != APLWC_OK)
+ if((aplwc->last_error = check_tokens(aplwc, module, tokens)) != APLWC_OK)
goto end;
module->link = aplwc->modules;
diff --git a/src/lib/syntax.c b/src/lib/syntax.c
index d864bf4..3354050 100644
--- a/src/lib/syntax.c
+++ b/src/lib/syntax.c
@@ -446,7 +446,6 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline)
for(i++; i < n; i++){
if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){
rc = APLWC_INVALID_SYNTAX;
- tokens = NULL;
goto end;
}
}
@@ -454,27 +453,40 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline)
end:
aplwc->last_error = rc;
+ if(aplwc->last_error != APLWC_OK)
+ tokens = NULL;
MEMPTRS_EXIT(aplwc);
return tokens;
}
static void
-resolve_unknown(struct aplwc_module *module, struct token *t)
+resolve_unknown(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens, size_t i)
{
symbol_t s;
struct module_member *m;
+ struct string *boot;
- assert(t && (t->tag == TOKEN_TAG_UNKNOWN_SYM));
- if(module == NULL)
- return;
+ MEMPTRS(aplwc, 3);
+ MEMPTR(0, module);
+ MEMPTR(1, tokens);
+
+ assert(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM);
+ if(module == NULL){
+ /* Try to look into the Boot module */
+ if((boot = chars_to_string(aplwc, "Boot", -1)) == NULL)
+ goto end;
+ MEMPTR(2, boot);
+ if((module = module_lookup(aplwc, boot)) == NULL)
+ goto end;
+ }
- s = t->data.symbol;
+ s = tokens->tokens[i].data.symbol;
for(m = module->members; m; m = m->link){
if(m->name == s){
found:
- t->tag = TOKEN_TAG_IDENTIFIER;
- return;
+ tokens->tokens[i].tag = TOKEN_TAG_IDENTIFIER;
+ goto end;
}
}
@@ -482,27 +494,35 @@ found:
if(m->name == s)
goto found;
}
+
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+end:
+ MEMPTRS_EXIT(aplwc);
}
enum aplwc_rc
-check_tokens(struct aplwc_module *module, struct token_list *tokens)
+check_tokens(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens)
{
size_t i;
- enum aplwc_rc rc;
- for(i = 0, rc = APLWC_OK; (rc == APLWC_OK) && (i < tokens->length); i++){
+ MEMPTRS(aplwc, 2);
+ MEMPTR(0, module);
+ MEMPTR(1, tokens);
+
+ for(i = 0, aplwc->last_error = APLWC_OK; (aplwc->last_error == APLWC_OK) && (i < tokens->length); i++){
switch(tokens->tokens[i].tag){
case TOKEN_TAG_UNKNOWN_SYM:
- resolve_unknown(module, &tokens->tokens[i]);
+ resolve_unknown(aplwc, module, tokens, i);
if(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM)
- return APLWC_INVALID_SYNTAX;
+ assert(aplwc->last_error != APLWC_OK);
break;
default:
break;
}
}
- return rc;
+ MEMPTRS_EXIT(aplwc);
+ return aplwc->last_error;
}
enum aplwc_rc