summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter <peter@pmikkelsen.com>2026-08-29 15:22:21 +0000
committerpeter <peter@pmikkelsen.com>2026-08-29 15:22:21 +0000
commita01b62d7ace95aef73b9f2d33f01486e0856233f (patch)
tree49738b1da92d7ee8b00b8d1fed93f4d3a0edef65
parent3787b5c0b7870eec43ce384beaa16288073e89cf (diff)
Commit unsaved work.
FossilOrigin-Name: 46adf8e389516e01f11696af5cf48d7dbee8764a480e20957a251538ace8cf3a
-rw-r--r--src/lib/aplwc_internal.h19
-rw-r--r--src/lib/main.c4
-rw-r--r--src/lib/memory.c16
-rw-r--r--src/lib/module.c65
-rw-r--r--src/lib/string.c20
-rw-r--r--src/lib/syntax.c31
6 files changed, 131 insertions, 24 deletions
diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h
index 888d35c..e394bd8 100644
--- a/src/lib/aplwc_internal.h
+++ b/src/lib/aplwc_internal.h
@@ -17,6 +17,7 @@ struct memory {
struct aplwc {
enum aplwc_rc last_error;
struct memory memory;
+ struct aplwc_module *modules;
};
struct aplwc_line {
@@ -42,7 +43,9 @@ enum token_tag {
TOKEN_TAG_DEL,
TOKEN_TAG_LEFT_PAREN,
TOKEN_TAG_RIGHT_PAREN,
- TOKEN_TAG_IBEAM
+ TOKEN_TAG_IBEAM,
+ TOKEN_TAG_QUAD,
+ TOKEN_TAG_UNKNOWN_SYM
};
struct token {
@@ -67,6 +70,13 @@ struct aplwc_value {
enum value_tag tag;
};
+struct aplwc_module {
+ struct aplwc *aplwc;
+ struct string *name;
+ struct token_list *tokens;
+ struct aplwc_module *link;
+};
+
/* eval.c */
struct aplwc_value *eval_line(struct aplwc_line *);
@@ -77,21 +87,28 @@ struct aplwc_line *memory_alloc_aplwc_line(struct memory *);
struct string *memory_alloc_string(struct memory *, size_t);
struct token_list *memory_alloc_token_list(struct memory *, size_t);
struct aplwc_value *memory_alloc_aplwc_value(struct memory *);
+struct aplwc_module *memory_alloc_aplwc_module(struct memory *);
+struct module_imports *memory_alloc_module_imports(struct memory *, size_t);
void memory_free_aplwc(struct memory *, struct aplwc *);
void memory_free_aplwc_line(struct memory *, struct aplwc_line *);
void memory_free_string(struct memory *, struct string *);
void memory_free_token_list(struct memory *, struct token_list *);
void memory_free_aplwc_value(struct memory *, struct aplwc_value *);
+void memory_free_aplwc_module(struct memory *, struct aplwc_module *);
/* string.c */
struct string *chars_to_string(struct aplwc *, const char *, int len);
uint32_t string_char(struct string *, size_t);
size_t char_length(struct string *, size_t);
+int string_compare(struct string *, struct string *);
/* syntax.c */
struct token_list *scan_string(struct aplwc *, struct string *, int);
+enum aplwc_rc check_tokens(struct token_list *);
/* module.c */
enum aplwc_rc load_module(struct aplwc *, struct string *, struct token_list *);
+struct aplwc_module *module_lookup(struct aplwc *, struct string *);
+struct string *module_imports_syms(struct module_imports *);
#endif /* APLWC_INTERNAL_H */
diff --git a/src/lib/main.c b/src/lib/main.c
index ae17f34..d6de538 100644
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -79,6 +79,10 @@ aplwc_read(struct aplwc *aplwc, const char *line)
if(tokens == NULL)
return NULL;
+ aplwc->last_error = check_tokens(tokens);
+ if(aplwc->last_error != APLWC_OK)
+ return NULL;
+
ret = memory_alloc_aplwc_line(&aplwc->memory);
if(ret == NULL){
aplwc->last_error = APLWC_OUT_OF_MEMORY;
diff --git a/src/lib/memory.c b/src/lib/memory.c
index f34ff43..a348b93 100644
--- a/src/lib/memory.c
+++ b/src/lib/memory.c
@@ -118,3 +118,19 @@ memory_free_aplwc_value(struct memory *m, struct aplwc_value *p)
UNUSED_PARAMETER(m);
UNUSED_PARAMETER(p);
}
+
+struct aplwc_module *
+memory_alloc_aplwc_module(struct memory *m)
+{
+ struct aplwc_module *p;
+
+ p = alloc(m, sizeof(struct aplwc_module), alignof(struct aplwc_module));
+ return p;
+}
+
+void
+memory_free_aplwc_module(struct memory *m, struct aplwc_module *p)
+{
+ UNUSED_PARAMETER(m);
+ UNUSED_PARAMETER(p);
+}
diff --git a/src/lib/module.c b/src/lib/module.c
index 4ce9f8c..9a202f9 100644
--- a/src/lib/module.c
+++ b/src/lib/module.c
@@ -1,53 +1,50 @@
#include "aplwc_internal.h"
static int
-read_keyword_decl(struct token_list *tokens, size_t offset)
+read_keyword_decl(struct aplwc_module *module, size_t offset)
{
int len;
- for(len = 1; (offset + len) < tokens->length; len++)
- if(tokens->tokens[offset+len].tag == TOKEN_TAG_NEWLINE)
+ for(len = 1; (offset + len) < module->tokens->length; len++)
+ if(module->tokens->tokens[offset+len].tag == TOKEN_TAG_NEWLINE)
break;
return len;
}
static int
-read_function_decl(struct token_list *tokens, size_t offset)
+read_function_decl(struct aplwc_module *module, size_t offset)
{
int len;
- for(len = 1; (offset + len) < tokens->length; len++)
- if(tokens->tokens[offset+len].tag == TOKEN_TAG_DEL)
+ for(len = 1; (offset + len) < module->tokens->length; len++)
+ if(module->tokens->tokens[offset+len].tag == TOKEN_TAG_DEL)
break;
return len;
}
static int
-read_decl(struct token_list *tokens, size_t offset)
+read_decl(struct aplwc_module *module, size_t offset)
{
- UNUSED_PARAMETER(tokens);
- UNUSED_PARAMETER(offset);
-
- switch(tokens->tokens[offset].tag){
+ switch(module->tokens->tokens[offset].tag){
case TOKEN_TAG_NEWLINE:
return 0;
case TOKEN_TAG_KEYWORD:
- return read_keyword_decl(tokens, offset);
+ return read_keyword_decl(module, offset);
case TOKEN_TAG_DEL:
- return read_function_decl(tokens, offset);
+ return read_function_decl(module, offset);
default:
return -1;
}
}
static enum aplwc_rc
-read_decls(struct token_list *tokens)
+read_decls(struct aplwc_module *module)
{
size_t offset;
int skip;
- for(offset = 0; offset < tokens->length; offset++){
- skip = read_decl(tokens, offset);
+ for(offset = 0; offset < module->tokens->length; offset++){
+ skip = read_decl(module, offset);
if(skip == -1)
return APLWC_INVALID_SYNTAX;
offset += skip;
@@ -58,8 +55,38 @@ read_decls(struct token_list *tokens)
enum aplwc_rc
load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens)
{
- UNUSED_PARAMETER(aplwc);
- UNUSED_PARAMETER(name);
+ enum aplwc_rc rc;
+ struct aplwc_module *module;
+
+ module = memory_alloc_aplwc_module(&aplwc->memory);
+ if(module == NULL){
+ aplwc->last_error = APLWC_OUT_OF_MEMORY;
+ return aplwc->last_error;
+ }
+ module->aplwc = aplwc;
+ module->name = name;
+ module->tokens = tokens;
+ module->link = NULL;
- return read_decls(tokens);
+ rc = read_decls(module);
+ if(rc == APLWC_OK){
+ module->link = aplwc->modules;
+ aplwc->modules = module;
+ }else{
+ memory_free_aplwc_module(&aplwc->memory, module);
+ }
+
+ return rc;
+}
+
+struct aplwc_module *
+module_lookup(struct aplwc *aplwc, struct string *name)
+{
+ struct aplwc_module *m;
+
+ for(m = aplwc->modules; m; m = m->link){
+ if(string_compare(m->name, name) == 0)
+ break;
+ }
+ return m;
}
diff --git a/src/lib/string.c b/src/lib/string.c
index ecac9d7..24f978c 100644
--- a/src/lib/string.c
+++ b/src/lib/string.c
@@ -130,3 +130,23 @@ char_length(struct string *string, size_t offset)
else
return 4;
}
+
+int
+string_compare(struct string *a, struct string *b)
+{
+ size_t i;
+
+ for(i = 0; (i < a->bytes) && (i < b->bytes); i++){
+ if(a->utf8[i] < b->utf8[i])
+ return -1;
+ else if(a->utf8[i] > b->utf8[i])
+ return 1;
+ }
+
+ if(a->bytes < b->bytes)
+ return -1;
+ else if(a->bytes > b->bytes)
+ return 1;
+ else
+ return 0;
+}
diff --git a/src/lib/syntax.c b/src/lib/syntax.c
index 89f8be4..395c75e 100644
--- a/src/lib/syntax.c
+++ b/src/lib/syntax.c
@@ -56,16 +56,20 @@ skip_space(struct scan_state *state)
static int
single_sym(struct scan_state *state, struct token *token)
{
- switch(peek(state)){
+ uint32_t c;
+
+ c = peek(state);
+
+ switch(c){
case 0x2190: token->tag = TOKEN_TAG_LEFT_ARROW; break;
case 0x22C4: token->tag = TOKEN_TAG_DIAMOND; break;
case 0x2207: token->tag = TOKEN_TAG_DEL; break;
case 0x2336: token->tag = TOKEN_TAG_IBEAM; break;
+ case 0x2395: token->tag = TOKEN_TAG_QUAD; break;
case '\n': token->tag = TOKEN_TAG_NEWLINE; break;
case '(': token->tag = TOKEN_TAG_LEFT_PAREN; break;
case ')': token->tag = TOKEN_TAG_RIGHT_PAREN; break;
- default:
- return 0;
+ default: token->tag = TOKEN_TAG_UNKNOWN_SYM; break;
}
advance(state);
@@ -172,11 +176,11 @@ next_token(struct scan_state *state, struct token *token)
{
size_t i;
int (*scans[])(struct scan_state *, struct token *token) = {
- single_sym,
identifier,
keyword,
number,
text,
+ single_sym /* Must be last */
};
skip_space(state);
@@ -265,3 +269,22 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline)
return tokens;
}
+
+enum aplwc_rc
+check_tokens(struct token_list *tokens)
+{
+ size_t i;
+ enum aplwc_rc rc;
+
+ for(i = 0, rc = APLWC_OK; (rc == APLWC_OK) && (i < tokens->length); i++){
+ switch(tokens->tokens[i].tag){
+ case TOKEN_TAG_UNKNOWN_SYM:
+ rc = APLWC_INVALID_SYNTAX;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return rc;
+}