aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.md20
-rw-r--r--src/ast.c5
-rw-r--r--src/ast.h5
-rw-r--r--src/compile/expressions.c1
-rw-r--r--src/compile/files.c15
-rw-r--r--src/compile/functions.c5
-rw-r--r--src/compile/headers.c17
-rw-r--r--src/compile/statements.c1
-rw-r--r--src/formatter/formatter.c5
-rw-r--r--src/formatter/utils.c6
-rw-r--r--src/parse/files.c5
-rw-r--r--src/parse/typedefs.c27
-rw-r--r--src/parse/typedefs.h1
-rw-r--r--src/parse/utils.c7
-rw-r--r--src/typecheck.c61
15 files changed, 24 insertions, 157 deletions
diff --git a/CHANGES.md b/CHANGES.md
index bfac654b..0c34e86c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,15 +11,17 @@
- Syntax for text literals and inline C code has been simplified somewhat.
- Syntax for tables has changed to use colons (`{k: v}`) instead of equals
(`{k=v}`).
-- Deprecated sets.
- - Instead of sets, use tables.
- - Tables now have `and`, `or`, `xor`, and `-` (minus) metamethods.
-- Deprecated `extern` keyword for declaring external symbols from C.
- - Use `C_code` instead.
-- Deprecated the postfix `?` to make values optional.
- - Explicitly optional values can be declared as `my_var : T? = value`.
-- Deprecated `>> ... = ...` form of doctests. They are now called "debug logs"
- and you can specify multiple values: `>> a, b, c`
+- Deprecated:
+ - Sets
+ - Instead of sets, use tables.
+ - Tables now have `and`, `or`, `xor`, and `-` (minus) metamethods.
+ - `extern` keyword for declaring external symbols from C.
+ - Use `C_code` instead.
+ - Postfix `?` to make values optional.
+ - Explicitly optional values can be declared as `my_var : T? = value`.
+ - `>> ... = ...` form of doctests. They are now called "debug logs" and you
+ can specify multiple values: `>> a, b, c`
+ - `extend` blocks
- Struct fields that start with underscores can be accessed again and function
arguments that start with underscore can be passed (but only as keyword
arguments).
diff --git a/src/ast.c b/src/ast.c
index 302ced72..dfc1213c 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -275,7 +275,6 @@ Text_t ast_to_sexp(ast_t *ast) {
T(Use, "(Use ", optional_sexp("var", data.var), " ", quoted_text(data.path), ")");
T(InlineCCode, "(InlineCCode ", ast_list_to_sexp(data.chunks), optional_type_sexp("type", data.type_ast), ")");
T(Deserialize, "(Deserialize ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), ")");
- T(Extend, "(Extend \"", data.name, "\" ", ast_to_sexp(data.body), ")");
default: errx(1, "S-expressions are not implemented for this AST");
#undef T
}
@@ -681,10 +680,6 @@ void ast_visit(ast_t *ast, void (*visitor)(ast_t *, void *), void *userdata) {
ast_visit(Match(ast, Deserialize)->value, visitor, userdata);
return;
}
- case Extend: {
- ast_visit(Match(ast, Extend)->body, visitor, userdata);
- return;
- }
default: errx(1, "Visiting is not supported for this AST: %s", Text$as_c_string(ast_to_sexp(ast)));
#undef T
}
diff --git a/src/ast.h b/src/ast.h
index 142bea19..60cd9077 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -275,7 +275,6 @@ typedef enum {
Use,
InlineCCode,
Deserialize,
- Extend,
ExplicitlyTyped,
} ast_e;
#define NUM_AST_TAGS (ExplicitlyTyped + 1)
@@ -459,10 +458,6 @@ struct ast_s {
type_ast_t *type;
} Deserialize;
struct {
- const char *name;
- ast_t *body;
- } Extend;
- struct {
ast_t *ast;
struct type_s *type;
} ExplicitlyTyped;
diff --git a/src/compile/expressions.c b/src/compile/expressions.c
index b9fafeb8..098ed4ca 100644
--- a/src/compile/expressions.c
+++ b/src/compile/expressions.c
@@ -241,7 +241,6 @@ Text_t compile(env_t *env, ast_t *ast) {
case Repeat:
case StructDef:
case LangDef:
- case Extend:
case EnumDef:
case FunctionDef:
case ConvertDef:
diff --git a/src/compile/files.c b/src/compile/files.c
index f331a50a..a4cc07fe 100644
--- a/src/compile/files.c
+++ b/src/compile/files.c
@@ -48,8 +48,6 @@ void initialize_vars_and_statics(env_t *env, ast_t *ast) {
initialize_namespace(env, Match(stmt->ast, EnumDef)->name, Match(stmt->ast, EnumDef)->namespace);
} else if (stmt->ast->tag == LangDef) {
initialize_namespace(env, Match(stmt->ast, LangDef)->name, Match(stmt->ast, LangDef)->namespace);
- } else if (stmt->ast->tag == Extend) {
- initialize_namespace(env, Match(stmt->ast, Extend)->name, Match(stmt->ast, Extend)->body);
} else if (stmt->ast->tag == Use) {
continue;
} else {
@@ -137,19 +135,6 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) {
", .metamethods=Text$metamethods, .tag=TextInfo, .TextInfo={", quoted_str(def->name), "}};\n");
return Texts(code, compile_namespace(env, def->name, def->namespace));
}
- case Extend: {
- DeclareMatch(extend, ast, Extend);
- binding_t *b = get_binding(env, extend->name);
- if (!b || b->type->tag != TypeInfoType)
- code_err(ast, "'", extend->name, "' is not the name of any type I recognize.");
- env_t *ns_env = Match(b->type, TypeInfoType)->env;
- env_t *extended = new (env_t);
- *extended = *ns_env;
- extended->locals = new (Table_t, .fallback = env->locals);
- extended->namespace_bindings = new (Table_t, .fallback = env->namespace_bindings);
- extended->id_suffix = env->id_suffix;
- return compile_top_level_code(extended, extend->body);
- }
case Block: {
Text_t code = EMPTY_TEXT;
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
diff --git a/src/compile/functions.c b/src/compile/functions.c
index 40e16e48..ab267e2c 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -580,10 +580,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
case ConvertDef:
case StructDef:
case EnumDef:
- case LangDef:
- case Extend: {
- errx(1, "Definitions should not be reachable in a closure.");
- }
+ case LangDef: errx(1, "Definitions should not be reachable in a closure.");
default: break;
}
}
diff --git a/src/compile/headers.c b/src/compile/headers.c
index 1865905c..bc0156ad 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -25,20 +25,6 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t
block = def->namespace;
break;
}
- case Extend: {
- DeclareMatch(extend, ast, Extend);
- ns_env = namespace_env(env, extend->name);
-
- env_t *extended = new (env_t);
- *extended = *ns_env;
- extended->locals = new (Table_t, .fallback = env->locals);
- extended->namespace_bindings = new (Table_t, .fallback = env->namespace_bindings);
- extended->id_suffix = env->id_suffix;
- ns_env = extended;
-
- block = extend->body;
- break;
- }
case StructDef: {
DeclareMatch(def, ast, StructDef);
ns_env = namespace_env(env, def->name);
@@ -251,9 +237,6 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
"extern const TypeInfo_t ",
namespace_name(env, env->namespace, Texts(def->name, Text("$$info"))), ";\n");
}
- case Extend: {
- return EMPTY_TEXT;
- }
default: return EMPTY_TEXT;
}
}
diff --git a/src/compile/statements.c b/src/compile/statements.c
index 156cc8c0..a9ec4327 100644
--- a/src/compile/statements.c
+++ b/src/compile/statements.c
@@ -76,7 +76,6 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) {
case StructDef:
case EnumDef:
case LangDef:
- case Extend:
case FunctionDef:
case ConvertDef: {
return EMPTY_TEXT;
diff --git a/src/formatter/formatter.c b/src/formatter/formatter.c
index 9ff328d0..41b1c4aa 100644
--- a/src/formatter/formatter.c
+++ b/src/formatter/formatter.c
@@ -116,7 +116,6 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) {
/*inline*/ case StructDef:
/*inline*/ case EnumDef:
/*inline*/ case LangDef:
- /*inline*/ case Extend:
/*inline*/ case FunctionDef:
/*inline*/ case ConvertDef:
/*inline*/ case DebugLog:
@@ -571,10 +570,6 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) {
DeclareMatch(def, ast, LangDef);
return Texts("lang ", Text$from_str(def->name), format_namespace(def->namespace, comments, indent));
}
- /*multiline*/ case Extend: {
- DeclareMatch(extend, ast, Extend);
- return Texts("lang ", Text$from_str(extend->name), format_namespace(extend->body, comments, indent));
- }
/*multiline*/ case Defer:
return Texts("defer ", format_namespace(Match(ast, Defer)->body, comments, indent));
/*multiline*/ case List: {
diff --git a/src/formatter/utils.c b/src/formatter/utils.c
index 9829df4b..ce2d30b5 100644
--- a/src/formatter/utils.c
+++ b/src/formatter/utils.c
@@ -70,8 +70,7 @@ CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) {
case Lambda:
case StructDef:
case EnumDef:
- case LangDef:
- case Extend: return 1;
+ case LangDef: return 1;
case Use: {
if (second->tag != Use) return 1;
break;
@@ -104,8 +103,7 @@ CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) {
case Lambda:
case StructDef:
case EnumDef:
- case LangDef:
- case Extend: return 1;
+ case LangDef: return 1;
default: break;
}
return 0;
diff --git a/src/parse/files.c b/src/parse/files.c
index 5e0dc29c..2dbe0e8f 100644
--- a/src/parse/files.c
+++ b/src/parse/files.c
@@ -41,9 +41,8 @@ ast_t *parse_file_body(parse_ctx_t *ctx, const char *pos) {
ast_t *stmt;
if ((stmt = optional(ctx, &pos, parse_struct_def)) || (stmt = optional(ctx, &pos, parse_func_def))
|| (stmt = optional(ctx, &pos, parse_enum_def)) || (stmt = optional(ctx, &pos, parse_lang_def))
- || (stmt = optional(ctx, &pos, parse_extend)) || (stmt = optional(ctx, &pos, parse_convert_def))
- || (stmt = optional(ctx, &pos, parse_use)) || (stmt = optional(ctx, &pos, parse_inline_c))
- || (stmt = optional(ctx, &pos, parse_top_declaration))) {
+ || (stmt = optional(ctx, &pos, parse_convert_def)) || (stmt = optional(ctx, &pos, parse_use))
+ || (stmt = optional(ctx, &pos, parse_inline_c)) || (stmt = optional(ctx, &pos, parse_top_declaration))) {
statements = new (ast_list_t, .ast = stmt, .next = statements);
pos = stmt->end;
whitespace(ctx, &pos); // TODO: check for newline
diff --git a/src/parse/typedefs.c b/src/parse/typedefs.c
index fe48cb2c..56bb687f 100644
--- a/src/parse/typedefs.c
+++ b/src/parse/typedefs.c
@@ -26,9 +26,8 @@ ast_t *parse_namespace(parse_ctx_t *ctx, const char *pos) {
ast_t *stmt;
if ((stmt = optional(ctx, &pos, parse_struct_def)) || (stmt = optional(ctx, &pos, parse_func_def))
|| (stmt = optional(ctx, &pos, parse_enum_def)) || (stmt = optional(ctx, &pos, parse_lang_def))
- || (stmt = optional(ctx, &pos, parse_extend)) || (stmt = optional(ctx, &pos, parse_convert_def))
- || (stmt = optional(ctx, &pos, parse_use)) || (stmt = optional(ctx, &pos, parse_inline_c))
- || (stmt = optional(ctx, &pos, parse_declaration))) {
+ || (stmt = optional(ctx, &pos, parse_convert_def)) || (stmt = optional(ctx, &pos, parse_use))
+ || (stmt = optional(ctx, &pos, parse_inline_c)) || (stmt = optional(ctx, &pos, parse_declaration))) {
statements = new (ast_list_t, .ast = stmt, .next = statements);
pos = stmt->end;
whitespace(ctx, &pos); // TODO: check for newline
@@ -182,25 +181,3 @@ ast_t *parse_lang_def(parse_ctx_t *ctx, const char *pos) {
return NewAST(ctx->file, start, pos, LangDef, .name = name, .namespace = namespace);
}
-
-ast_t *parse_extend(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- // extend Name: body...
- if (!match_word(&pos, "extend")) return NULL;
- int64_t starting_indent = get_indent(ctx, pos);
- spaces(&pos);
- const char *name = get_id(&pos);
- if (!name) parser_err(ctx, start, pos, "I expected a name for this lang");
-
- ast_t *body = NULL;
- const char *ns_pos = pos;
- whitespace(ctx, &ns_pos);
- int64_t ns_indent = get_indent(ctx, ns_pos);
- if (ns_indent > starting_indent) {
- pos = ns_pos;
- body = optional(ctx, &pos, parse_namespace);
- }
- if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
-
- return NewAST(ctx->file, start, pos, Extend, .name = name, .body = body);
-}
diff --git a/src/parse/typedefs.h b/src/parse/typedefs.h
index 1a746cff..1bdb92e6 100644
--- a/src/parse/typedefs.h
+++ b/src/parse/typedefs.h
@@ -7,5 +7,4 @@
ast_t *parse_lang_def(parse_ctx_t *ctx, const char *pos);
ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos);
ast_t *parse_struct_def(parse_ctx_t *ctx, const char *pos);
-ast_t *parse_extend(parse_ctx_t *ctx, const char *pos);
ast_t *parse_namespace(parse_ctx_t *ctx, const char *pos);
diff --git a/src/parse/utils.c b/src/parse/utils.c
index 2048a3ff..28cf0964 100644
--- a/src/parse/utils.c
+++ b/src/parse/utils.c
@@ -12,10 +12,9 @@
#include "utils.h"
static const char *keywords[] = {
- "C_code", "_max_", "_min_", "and", "assert", "break", "continue", "defer", "deserialize", "do",
- "else", "enum", "extend", "for", "func", "if", "in", "lang", "mod", "mod1",
- "no", "none", "not", "or", "pass", "return", "skip", "skip", "stop", "struct",
- "then", "unless", "use", "when", "while", "xor", "yes",
+ "C_code", "_max_", "_min_", "and", "assert", "break", "continue", "defer", "deserialize", "do", "else", "enum",
+ "for", "func", "if", "in", "lang", "mod", "mod1", "no", "none", "not", "or", "pass",
+ "return", "skip", "skip", "stop", "struct", "then", "unless", "use", "when", "while", "xor", "yes",
};
CONSTFUNC bool is_keyword(const char *word) {
diff --git a/src/typecheck.c b/src/typecheck.c
index 21eb7b3f..b21fa40f 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -321,31 +321,6 @@ void prebind_statement(env_t *env, ast_t *statement) {
prebind_statement(ns_env, stmt->ast);
break;
}
- case Extend: {
- DeclareMatch(extend, statement, Extend);
- env_t *ns_env = namespace_env(env, extend->name);
- env_t *extended = new (env_t);
- *extended = *ns_env;
- extended->locals = new (Table_t, .fallback = env->locals);
- extended->namespace_bindings = new (Table_t, .fallback = env->namespace_bindings);
- extended->id_suffix = env->id_suffix;
- for (ast_list_t *stmt = extend->body ? Match(extend->body, Block)->statements : NULL; stmt; stmt = stmt->next)
- prebind_statement(extended, stmt->ast);
- List_t new_bindings = extended->locals->entries;
- for (int64_t i = 0; i < (int64_t)new_bindings.length; i++) {
- struct {
- const char *name;
- binding_t *binding;
- } *entry = new_bindings.data + i * new_bindings.stride;
- binding_t *clobbered = Table$str_get(*ns_env->locals, entry->name);
- if (clobbered && !type_eq(clobbered->type, entry->binding->type))
- code_err(statement, "This `extend` block overwrites the binding for ", quoted(entry->name),
- " in the original namespace (with type ", type_to_text(clobbered->type),
- ") with a new binding with type ", type_to_text(entry->binding->type));
- Table$str_set(ns_env->locals, entry->name, entry->binding);
- }
- break;
- }
default: break;
}
}
@@ -551,31 +526,6 @@ void bind_statement(env_t *env, ast_t *statement) {
bind_statement(ns_env, stmt->ast);
break;
}
- case Extend: {
- DeclareMatch(extend, statement, Extend);
- env_t *ns_env = namespace_env(env, extend->name);
- env_t *extended = new (env_t);
- *extended = *ns_env;
- extended->locals = new (Table_t, .fallback = env->locals);
- extended->namespace_bindings = new (Table_t, .fallback = env->namespace_bindings);
- extended->id_suffix = env->id_suffix;
- for (ast_list_t *stmt = extend->body ? Match(extend->body, Block)->statements : NULL; stmt; stmt = stmt->next)
- bind_statement(extended, stmt->ast);
- List_t new_bindings = extended->locals->entries;
- for (int64_t i = 0; i < (int64_t)new_bindings.length; i++) {
- struct {
- const char *name;
- binding_t *binding;
- } *entry = new_bindings.data + i * new_bindings.stride;
- binding_t *clobbered = Table$str_get(*ns_env->locals, entry->name);
- if (clobbered && !type_eq(clobbered->type, entry->binding->type))
- code_err(statement, "This `extend` block overwrites the binding for ", quoted(entry->name),
- " in the original namespace (with type ", type_to_text(clobbered->type),
- ") with a new binding with type ", type_to_text(entry->binding->type));
- Table$str_set(ns_env->locals, entry->name, entry->binding);
- }
- break;
- }
case Use: {
env_t *module_env = load_module(env, statement);
if (!module_env) break;
@@ -1074,8 +1024,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
case ConvertDef:
case StructDef:
case EnumDef:
- case LangDef:
- case Extend: return Type(VoidType);
+ case LangDef: return Type(VoidType);
default: break;
}
@@ -1421,10 +1370,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
case ConvertDef:
case StructDef:
case EnumDef:
- case LangDef:
- case Extend: {
- return Type(VoidType);
- }
+ case LangDef: return Type(VoidType);
case If: {
DeclareMatch(if_, ast, If);
@@ -1580,8 +1526,7 @@ PUREFUNC bool is_discardable(env_t *env, ast_t *ast) {
case StructDef:
case EnumDef:
case LangDef:
- case Use:
- case Extend: return true;
+ case Use: return true;
default: break;
}
type_t *t = get_type(env, ast);