Update ast interface
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** @brief The name of the module being imported. */
|
/** @brief The name of the module being imported. */
|
||||||
Token module_name;
|
const char* module_name;
|
||||||
|
|
||||||
/** @brief Whether the import is public or not. */
|
/** @brief Whether the import is public or not. */
|
||||||
bool is_public;
|
bool is_public;
|
||||||
@@ -53,7 +53,7 @@ struct TypeExpression{
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** @brief The name of the alias. */
|
/** @brief The name of the alias. */
|
||||||
Token name;
|
const char* name;
|
||||||
|
|
||||||
/** @brief The value of the alias. */
|
/** @brief The value of the alias. */
|
||||||
TypeExpression value;
|
TypeExpression value;
|
||||||
@@ -65,7 +65,7 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** @brief The name of the module. */
|
/** @brief The name of the module. */
|
||||||
Token name;
|
const char* name;
|
||||||
|
|
||||||
/** @brief The list of imports in the module. */
|
/** @brief The list of imports in the module. */
|
||||||
ImportDeclaration* imports;
|
ImportDeclaration* imports;
|
||||||
|
|||||||
+19
-5
@@ -22,7 +22,9 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
fprintf(stderr, "Out of memory\n");
|
fprintf(stderr, "Out of memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
module->name = t;
|
module->name = (const char*)malloc(t.text.length + 1);
|
||||||
|
memcpy((void*)module->name, t.text.data, t.text.length);
|
||||||
|
((char*)module->name)[t.text.length] = '\0';
|
||||||
module->imports = NULL;
|
module->imports = NULL;
|
||||||
module->import_count = 0;
|
module->import_count = 0;
|
||||||
module->aliases = NULL;
|
module->aliases = NULL;
|
||||||
@@ -60,8 +62,12 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
parser_free(module);
|
parser_free(module);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* name = (char*)malloc(t.text.length + 1);
|
||||||
|
memcpy(name, t.text.data, t.text.length);
|
||||||
|
name[t.text.length] = '\0';
|
||||||
|
|
||||||
module->imports[module->import_count] = (ImportDeclaration){ .module_name = t, .is_public = is_public };
|
module->imports[module->import_count] = (ImportDeclaration){ .module_name = name, .is_public = is_public };
|
||||||
module->import_count++;
|
module->import_count++;
|
||||||
|
|
||||||
t = tokenstream_next(ts);
|
t = tokenstream_next(ts);
|
||||||
@@ -72,8 +78,6 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now t holds the first non-import token. If it's not TOKEN_ALIAS, return.
|
|
||||||
// If it is, process it.
|
|
||||||
while (t.token == TOKEN_ALIAS) {
|
while (t.token == TOKEN_ALIAS) {
|
||||||
AliasDeclaration* new_aliases = realloc(module->aliases, (module->alias_count + 1) * sizeof(AliasDeclaration));
|
AliasDeclaration* new_aliases = realloc(module->aliases, (module->alias_count + 1) * sizeof(AliasDeclaration));
|
||||||
if (!new_aliases) {
|
if (!new_aliases) {
|
||||||
@@ -88,8 +92,11 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
parser_free(module);
|
parser_free(module);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
char* name = (char*)malloc(t.text.length + 1);
|
||||||
|
memcpy(name, t.text.data, t.text.length);
|
||||||
|
name[t.text.length] = '\0';
|
||||||
AliasDeclaration alias;
|
AliasDeclaration alias;
|
||||||
alias.name = t;
|
alias.name = name;
|
||||||
|
|
||||||
t = tokenstream_next(ts);
|
t = tokenstream_next(ts);
|
||||||
if (t.token != TOKEN_ASSIGN) {
|
if (t.token != TOKEN_ASSIGN) {
|
||||||
@@ -124,10 +131,17 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
void parser_free(Module* module) {
|
void parser_free(Module* module) {
|
||||||
if (module == NULL) return;
|
if (module == NULL) return;
|
||||||
if (module->imports != NULL) {
|
if (module->imports != NULL) {
|
||||||
|
for(size_t i = 0; i < module->import_count; i++) {
|
||||||
|
free((void*)module->imports[i].module_name);
|
||||||
|
}
|
||||||
free(module->imports);
|
free(module->imports);
|
||||||
}
|
}
|
||||||
if (module->aliases != NULL) {
|
if (module->aliases != NULL) {
|
||||||
|
for(size_t i = 0; i < module->alias_count; i++) {
|
||||||
|
free((void*)module->aliases[i].name);
|
||||||
|
}
|
||||||
free(module->aliases);
|
free(module->aliases);
|
||||||
}
|
}
|
||||||
|
free((void*)module->name);
|
||||||
free(module);
|
free(module);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -8,7 +8,7 @@ static void test_parser_module_name(void) {
|
|||||||
Module* m = parser_parse(ts);
|
Module* m = parser_parse(ts);
|
||||||
|
|
||||||
assert_not_null(m, "expected module to be parsed");
|
assert_not_null(m, "expected module to be parsed");
|
||||||
assert_string("my_module", m->name.text, "expected name 'my_module'");
|
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||||
parser_free(m);
|
parser_free(m);
|
||||||
tokenstream_close(ts);
|
tokenstream_close(ts);
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,11 @@ static void test_parser_imports(void) {
|
|||||||
Module* m = parser_parse(ts);
|
Module* m = parser_parse(ts);
|
||||||
|
|
||||||
assert_not_null(m, "expected module to be parsed");
|
assert_not_null(m, "expected module to be parsed");
|
||||||
assert_string("my_module", m->name.text, "expected name 'my_module'");
|
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||||
|
|
||||||
assert_not_null(m->imports, "expected imports to be parsed");
|
assert_not_null(m->imports, "expected imports to be parsed");
|
||||||
assert_int(1, (int)m->import_count, "expected one import");
|
assert_int(1, (int)m->import_count, "expected one import");
|
||||||
assert_string("other_module", m->imports[0].module_name.text, "expected import name 'other_module'");
|
assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'");
|
||||||
assert_false(m->imports[0].is_public, "expected import to not be public");
|
assert_false(m->imports[0].is_public, "expected import to not be public");
|
||||||
parser_free(m);
|
parser_free(m);
|
||||||
tokenstream_close(ts);
|
tokenstream_close(ts);
|
||||||
@@ -73,11 +73,11 @@ static void test_parser_public_imports(void) {
|
|||||||
Module* m = parser_parse(ts);
|
Module* m = parser_parse(ts);
|
||||||
|
|
||||||
assert_not_null(m, "expected module to be parsed");
|
assert_not_null(m, "expected module to be parsed");
|
||||||
assert_string("my_module", m->name.text, "expected name 'my_module'");
|
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||||
|
|
||||||
assert_not_null(m->imports, "expected imports to be parsed");
|
assert_not_null(m->imports, "expected imports to be parsed");
|
||||||
assert_int(1, (int)m->import_count, "expected one import");
|
assert_int(1, (int)m->import_count, "expected one import");
|
||||||
assert_string("other_module", m->imports[0].module_name.text, "expected import name 'other_module'");
|
assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'");
|
||||||
assert_true(m->imports[0].is_public, "expected import to be public");
|
assert_true(m->imports[0].is_public, "expected import to be public");
|
||||||
parser_free(m);
|
parser_free(m);
|
||||||
tokenstream_close(ts);
|
tokenstream_close(ts);
|
||||||
@@ -86,9 +86,9 @@ static void test_parser_public_imports(void) {
|
|||||||
static void test_parser_alias_simple(void) {
|
static void test_parser_alias_simple(void) {
|
||||||
Module* m = test_get_ast();
|
Module* m = test_get_ast();
|
||||||
|
|
||||||
assert_int(1, m->alias_count, "expected correct number of aliases");
|
assert_int(1, (int)m->alias_count, "expected correct number of aliases");
|
||||||
AliasDeclaration alias = m->aliases[0];
|
AliasDeclaration alias = m->aliases[0];
|
||||||
assert_string("myalias", alias.name.text, "expected correct alias name");
|
assert_str("myalias", alias.name, "expected correct alias name");
|
||||||
assert_int(TYPE_EXPRESSION_BUILTIN, alias.value.tag, "expected correct alias tag");
|
assert_int(TYPE_EXPRESSION_BUILTIN, alias.value.tag, "expected correct alias tag");
|
||||||
assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32");
|
assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32");
|
||||||
assert_true(alias.value.builtin.isSigned, "expected signed");
|
assert_true(alias.value.builtin.isSigned, "expected signed");
|
||||||
|
|||||||
Reference in New Issue
Block a user