diff --git a/Makefile b/Makefile index 4c66d17..eb08573 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 d9e15d0..966018f 100644 --- a/builtins/text.c +++ b/builtins/text.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -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 798b559..017a280 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 485e247..83f8854 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 250e315..460ec0d 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 dfe1c66..d78476d 100644 --- a/test/lang.tm +++ b/test/lang.tm @@ -18,6 +18,9 @@ func main(): >> HTML.HEADER = $HTML"" + >> HTML.HEADER.text_content + = "" + >> user := "I <3 hax" >> html := $HTML"Hello $user!" = $HTML"Hello I <3 hax!" diff --git a/typecheck.c b/typecheck.c index 3d40da3..e74396c 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 8cb534d..a193561 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) {