aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-19 14:29:58 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-19 14:29:58 -0400
commit934b843b1ce4744f8f21b7c590f0e1f31c94f604 (patch)
tree5ca8d6f2a6c1055b8c2aa6e01f45b8e1e435aeff
parentea6f9797be2b6c1f65cf3b5594f8fb062ba92e9e (diff)
Add .text_content as a field on DSLs instead of a method
-rw-r--r--Makefile4
-rw-r--r--builtins/text.c11
-rw-r--r--builtins/text.h1
-rw-r--r--compile.c8
-rw-r--r--environment.c1
-rw-r--r--test/lang.tm3
-rw-r--r--typecheck.c3
-rw-r--r--types.c5
8 files changed, 31 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 4c66d174..eb085734 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ EXTRA=
G=-ggdb
O=-Og
CFLAGS=$(CCONFIG) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS)
-LDLIBS=-lgc -lcord -lm -lunistring -lgmp -ldl
+LDLIBS=-lgc -lcord -lreadline -lm -lunistring -lgmp -ldl
BUILTIN_OBJS=builtins/array.o builtins/bool.o builtins/channel.o builtins/nums.o builtins/functions.o builtins/integers.o \
builtins/pointer.o builtins/memory.o builtins/text.o builtins/thread.o builtins/where.o builtins/c_string.o builtins/table.o \
builtins/types.o builtins/util.o builtins/files.o builtins/range.o
@@ -35,7 +35,7 @@ tomo: tomo.o $(BUILTIN_OBJS) SipHash/halfsiphash.o ast.o parse.o environment.o t
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
libtomo.so: $(BUILTIN_OBJS) SipHash/halfsiphash.o
- $(CC) $^ $(CFLAGS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) -lgc -lcord -lm -lunistring -lgmp -ldl -Wl,-soname,libtomo.so -shared -o $@
+ $(CC) $^ $(CFLAGS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) -lgc -lcord -lreadline -lm -lunistring -lgmp -ldl -Wl,-soname,libtomo.so -shared -o $@
SipHash/halfsiphash.c:
git submodule update --init --recursive
diff --git a/builtins/text.c b/builtins/text.c
index d9e15d03..966018f1 100644
--- a/builtins/text.c
+++ b/builtins/text.c
@@ -7,6 +7,8 @@
#include <gc/cord.h>
#include <gmp.h>
#include <limits.h>
+#include <readline/history.h>
+#include <readline/readline.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -398,6 +400,15 @@ public array_t Text$character_names(CORD text)
return ret;
}
+public CORD Text$read_line(CORD prompt)
+{
+ char *line = readline(CORD_to_const_char_star(prompt));
+ if (!line) return CORD_EMPTY;
+ CORD ret = CORD_from_char_star(line);
+ free(line);
+ return ret;
+}
+
public const TypeInfo $Text = {
.size=sizeof(CORD),
.align=__alignof__(CORD),
diff --git a/builtins/text.h b/builtins/text.h
index 798b559e..017a2804 100644
--- a/builtins/text.h
+++ b/builtins/text.h
@@ -41,6 +41,7 @@ Int_t Text$num_clusters(CORD text);
Int_t Text$num_codepoints(CORD text);
Int_t Text$num_bytes(CORD text);
array_t Text$character_names(CORD text);
+CORD Text$read_line(CORD prompt);
extern const TypeInfo $Text;
diff --git a/compile.c b/compile.c
index 485e247f..83f88544 100644
--- a/compile.c
+++ b/compile.c
@@ -2636,6 +2636,14 @@ CORD compile(env_t *env, ast_t *ast)
if (!b->code) code_err(ast, "I couldn't figure out how to compile this field");
return b->code;
}
+ case TextType: {
+ const char *lang = Match(value_t, TextType)->lang;
+ if (lang && streq(f->field, "text_content")) {
+ CORD text = compile_to_pointer_depth(env, f->fielded, 0, false);
+ return CORD_all("((Text_t)", text, ")");
+ }
+ code_err(ast, "There is no '%s' field on %T values", f->field, value_t);
+ }
case StructType: {
for (arg_t *field = Match(value_t, StructType)->fields; field; field = field->next) {
if (streq(field->name, f->field)) {
diff --git a/environment.c b/environment.c
index 250e3153..460ec0df 100644
--- a/environment.c
+++ b/environment.c
@@ -260,6 +260,7 @@ env_t *new_compilation_unit(CORD *libname)
{"num_clusters", "Text$num_clusters", "func(text:Text)->Int"},
{"num_codepoints", "Text$num_codepoints", "func(text:Text)->Int"},
{"quoted", "Text$quoted", "func(text:Text, color=no)->Text"},
+ {"read_line", "Text$read_line", "func(prompt='')->Text"},
{"replace", "Text$replace", "func(text:Text, pattern:Text, replacement:Text, limit=-1)->Text"},
{"split", "Text$split", "func(text:Text, split:Text)->[Text]"},
{"title", "Text$title", "func(text:Text)->Text"},
diff --git a/test/lang.tm b/test/lang.tm
index dfe1c663..d78476de 100644
--- a/test/lang.tm
+++ b/test/lang.tm
@@ -18,6 +18,9 @@ func main():
>> HTML.HEADER
= $HTML"<!DOCTYPE HTML>"
+ >> HTML.HEADER.text_content
+ = "<!DOCTYPE HTML>"
+
>> user := "I <3 hax"
>> html := $HTML"Hello $user!"
= $HTML"Hello I &lt;3 hax!"
diff --git a/typecheck.c b/typecheck.c
index 3d40da3c..e74396c1 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -361,9 +361,6 @@ void bind_statement(env_t *env, ast_t *statement)
set_binding(ns_env, "from_unsafe_text",
new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type),
.code=CORD_all("(", namespace_prefix(env->libname, env->namespace), def->name, "_t)")));
- set_binding(ns_env, "text_content",
- new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=type), .ret=TEXT_TYPE),
- .code="(Text_t)"));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
bind_statement(ns_env, stmt->ast);
diff --git a/types.c b/types.c
index 8cb534d7..a1935616 100644
--- a/types.c
+++ b/types.c
@@ -586,6 +586,11 @@ type_t *get_field_type(type_t *t, const char *field_name)
switch (t->tag) {
case PointerType:
return get_field_type(Match(t, PointerType)->pointed, field_name);
+ case TextType: {
+ if (Match(t, TextType)->lang && streq(field_name, "text_content"))
+ return Type(TextType);
+ return NULL;
+ }
case StructType: {
auto struct_t = Match(t, StructType);
for (arg_t *field = struct_t->fields; field; field = field->next) {