aboutsummaryrefslogtreecommitdiff
path: root/src/typecheck.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-01 14:05:10 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-01 14:05:10 -0400
commit4d59fc2987e52da0274e6b204a9d2885613f74b7 (patch)
tree8c262f99cb6ae9b550b9f8abf0ab0477044d087a /src/typecheck.c
parent7a2c99de74f5870e1dea5b59d049678ad0ef8e44 (diff)
Move patterns into a module
Diffstat (limited to 'src/typecheck.c')
-rw-r--r--src/typecheck.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/typecheck.c b/src/typecheck.c
index 0bfe6a07..ff609435 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -12,7 +12,6 @@
#include "cordhelpers.h"
#include "environment.h"
#include "parse.h"
-#include "stdlib/patterns.h"
#include "stdlib/paths.h"
#include "stdlib/tables.h"
#include "stdlib/text.h"
@@ -195,8 +194,11 @@ static env_t *load_module(env_t *env, ast_t *module_ast)
env_t *module_env = fresh_scope(env);
Table$str_set(env->imports, use->path, module_env);
- char *libname_id = Text$as_c_string(
- Text$replace(Text$from_str(use->path), Pattern("{1+ !alphanumeric}"), Text("_"), Pattern(""), false));
+ char *libname_id = String(use->path);
+ for (char *p = libname_id; *p; p++) {
+ if (!isalnum(*p) && *p != '_')
+ *p = '_';
+ }
module_env->libname = libname_id;
for (size_t i = 0; i < tm_files.gl_pathc; i++) {
const char *filename = tm_files.gl_pathv[i];
@@ -269,6 +271,14 @@ void prebind_statement(env_t *env, ast_t *statement)
prebind_statement(ns_env, stmt->ast);
break;
}
+ case Extend: {
+ auto extend = Match(statement, Extend);
+ env_t *ns_env = namespace_env(env, extend->name);
+ ns_env->libname = env->libname;
+ for (ast_list_t *stmt = extend->body ? Match(extend->body, Block)->statements : NULL; stmt; stmt = stmt->next)
+ prebind_statement(ns_env, stmt->ast);
+ break;
+ }
default: break;
}
}
@@ -435,6 +445,14 @@ void bind_statement(env_t *env, ast_t *statement)
bind_statement(ns_env, stmt->ast);
break;
}
+ case Extend: {
+ auto extend = Match(statement, Extend);
+ env_t *ns_env = namespace_env(env, extend->name);
+ ns_env->libname = env->libname;
+ for (ast_list_t *stmt = extend->body ? Match(extend->body, Block)->statements : NULL; stmt; stmt = stmt->next)
+ bind_statement(ns_env, stmt->ast);
+ break;
+ }
case Use: {
env_t *module_env = load_module(env, statement);
if (!module_env) break;
@@ -940,7 +958,7 @@ type_t *get_type(env_t *env, ast_t *ast)
// Early out if the type is knowable without any context from the block:
switch (last->ast->tag) {
- case UpdateAssign: case Assign: case Declare: case FunctionDef: case ConvertDef: case StructDef: case EnumDef: case LangDef:
+ case UpdateAssign: case Assign: case Declare: case FunctionDef: case ConvertDef: case StructDef: case EnumDef: case LangDef: case Extend:
return Type(VoidType);
default: break;
}
@@ -1240,7 +1258,7 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(ClosureType, Type(FunctionType, .args=args, .ret=ret));
}
- case FunctionDef: case ConvertDef: case StructDef: case EnumDef: case LangDef: {
+ case FunctionDef: case ConvertDef: case StructDef: case EnumDef: case LangDef: case Extend: {
return Type(VoidType);
}
@@ -1399,7 +1417,7 @@ PUREFUNC bool is_discardable(env_t *env, ast_t *ast)
{
switch (ast->tag) {
case UpdateAssign: case Assign: case Declare: case FunctionDef: case ConvertDef: case StructDef: case EnumDef:
- case LangDef: case Use:
+ case LangDef: case Use: case Extend:
return true;
default: break;
}