aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-18 20:39:57 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-18 20:39:57 -0400
commit967b649da20f1cb2011025456853cb55f25e9a88 (patch)
treeffce4f06f5fbb833c8aee2ba7c6982156f7bfac4
parentd804b09b02b9c4a6ea6b16ae85524a704796cbc1 (diff)
Deprecate `#` operator in favor of .length and fix up some issues
-rw-r--r--ast.c1
-rw-r--r--ast.h4
-rw-r--r--compile.c50
-rw-r--r--parse.c9
-rw-r--r--test/arrays.tm6
-rw-r--r--test/iterators.tm2
-rw-r--r--test/nums.tm3
-rw-r--r--test/tables.tm4
-rw-r--r--test/text.tm4
-rw-r--r--typecheck.c1
10 files changed, 23 insertions, 61 deletions
diff --git a/ast.c b/ast.c
index 02cf51fa..07c27bf9 100644
--- a/ast.c
+++ b/ast.c
@@ -107,7 +107,6 @@ CORD ast_to_xml(ast_t *ast)
T(Assign, "<Assign><targets>%r</targets><values>%r</values></Assign>", ast_list_to_xml(data.targets), ast_list_to_xml(data.values))
T(BinaryOp, "<BinaryOp op=\"%r\">%r %r</BinaryOp>", xml_escape(OP_NAMES[data.op]), ast_to_xml(data.lhs), ast_to_xml(data.rhs))
T(UpdateAssign, "<UpdateAssign op=\"%r\">%r %r</UpdateAssign>", xml_escape(OP_NAMES[data.op]), ast_to_xml(data.lhs), ast_to_xml(data.rhs))
- T(Length, "<Length>%r</Length>", ast_to_xml(data.value))
T(Negative, "<Negative>%r</Negative>", ast_to_xml(data.value))
T(Not, "<Not>%r</Not>", ast_to_xml(data.value))
T(HeapAllocate, "<HeapAllocate>%r</HeapAllocate>", ast_to_xml(data.value))
diff --git a/ast.h b/ast.h
index d824c181..c98ac674 100644
--- a/ast.h
+++ b/ast.h
@@ -107,7 +107,7 @@ typedef enum {
TextLiteral, TextJoin, PrintStatement,
Declare, Assign,
BinaryOp, UpdateAssign,
- Length, Not, Negative, HeapAllocate, StackReference,
+ Not, Negative, HeapAllocate, StackReference,
Min, Max,
Array, Channel, Set, Table, TableEntry, Comprehension,
FunctionDef, Lambda,
@@ -174,7 +174,7 @@ struct ast_s {
} BinaryOp, UpdateAssign;
struct {
ast_t *value;
- } Length, Not, Negative, HeapAllocate, StackReference;
+ } Not, Negative, HeapAllocate, StackReference;
struct {
ast_t *lhs, *rhs, *key;
} Min, Max;
diff --git a/compile.c b/compile.c
index 5e97d0ea..fb60e387 100644
--- a/compile.c
+++ b/compile.c
@@ -1259,6 +1259,14 @@ CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target)
if (target->tag == BigIntType)
return compile(env, ast);
+ if (ast->tag != Int) {
+ CORD code = compile(env, ast);
+ type_t *actual_type = get_type(env, ast);
+ if (!promote(env, &code, actual_type, target))
+ code = CORD_all(type_to_cord(actual_type), "_to_", type_to_cord(target), "(", code, ", no)");
+ return code;
+ }
+
int64_t target_bits = (int64_t)Match(target, IntType)->bits;
Int_t int_val = Int$from_text(Match(ast, Int)->str);
mpz_t i;
@@ -1500,38 +1508,6 @@ CORD compile(env_t *env, ast_t *ast)
default: code_err(ast, "This is not a valid number bit width");
}
}
- case Length: {
- ast_t *expr = Match(ast, Length)->value;
- type_t *t = get_type(env, expr);
- switch (value_type(t)->tag) {
- case TextType: {
- CORD str = compile_to_pointer_depth(env, expr, 0, false);
- return CORD_all("Text$num_clusters(", str, ")");
- }
- case ArrayType: {
- if (t->tag == PointerType) {
- CORD arr = compile_to_pointer_depth(env, expr, 1, false);
- return CORD_all("I((", arr, ")->length)");
- } else {
- CORD arr = compile_to_pointer_depth(env, expr, 0, false);
- return CORD_all("I((", arr, ").length)");
- }
- }
- case TableType: {
- if (t->tag == PointerType) {
- CORD table = compile_to_pointer_depth(env, expr, 1, false);
- return CORD_all("I((", table, ")->entries.length)");
- } else {
- CORD table = compile_to_pointer_depth(env, expr, 0, false);
- return CORD_all("I((", table, ").entries.length)");
- }
- }
- default: {
- code_err(ast, "Length is not implemented for %T values", t);
- }
- }
- break;
- }
case Not: {
ast_t *value = Match(ast, Not)->value;
type_t *t = get_type(env, ast);
@@ -1547,10 +1523,14 @@ CORD compile(env_t *env, ast_t *ast)
return CORD_all("!(", compile(env, value), ")");
else if (t->tag == IntType)
return CORD_all("~(", compile(env, value), ")");
- else if (t->tag == ArrayType || t->tag == TableType)
- return CORD_all("!(", compile(env, WrapAST(ast, Length, value)), ")");
+ else if (t->tag == ArrayType)
+ return CORD_all("((", compile(env, value), ").length == 0)");
+ else if (t->tag == SetType || t->tag == TableType)
+ return CORD_all("((", compile(env, value), ").entries.length == 0)");
else if (t->tag == TextType)
- return CORD_all("!(", compile(env, value), ")");
+ return CORD_all("(", compile(env, value), " == CORD_EMPTY)");
+ else if (t->tag == PointerType && Match(t, PointerType)->is_optional)
+ return CORD_all("(", compile(env, value), " == NULL)");
code_err(ast, "I don't know how to negate values of type %T", t);
}
diff --git a/parse.c b/parse.c
index 3b5974aa..c8e91d00 100644
--- a/parse.c
+++ b/parse.c
@@ -1089,14 +1089,6 @@ PARSER(parse_while) {
return NewAST(ctx->file, start, pos, While, .condition=condition, .body=body);
}
-PARSER(parse_length) {
- const char *start = pos;
- if (!match(&pos, "#")) return NULL;
- spaces(&pos);
- ast_t *val = expect(ctx, start, &pos, parse_term, "I expected an expression for this '#'");
- return NewAST(ctx->file, start, pos, Length, .value=val);
-}
-
PARSER(parse_heap_alloc) {
const char *start = pos;
if (!match(&pos, "@")) return NULL;
@@ -1335,7 +1327,6 @@ PARSER(parse_term_no_suffix) {
|| (term=parse_nil(ctx, pos))
|| (term=parse_num(ctx, pos))
|| (term=parse_int(ctx, pos))
- || (term=parse_length(ctx, pos))
|| (term=parse_negative(ctx, pos))
|| (term=parse_heap_alloc(ctx, pos))
|| (term=parse_stack_reference(ctx, pos))
diff --git a/test/arrays.tm b/test/arrays.tm
index 76507c5b..ac243018 100644
--- a/test/arrays.tm
+++ b/test/arrays.tm
@@ -12,7 +12,7 @@ func main():
>> arr[-1]
= 30
- >> #arr
+ >> arr.length
= 3
sum := 0
@@ -105,7 +105,7 @@ func main():
>> heap:heapify()
>> heap
sorted := [:Int]
- while #heap > 0:
+ while heap.length > 0:
sorted:insert(heap:heap_pop())
>> sorted == sorted:sorted()
= yes
@@ -113,7 +113,7 @@ func main():
heap:heap_push(Int.random(1, 50))
>> heap
sorted = [:Int]
- while #heap > 0:
+ while heap.length > 0:
sorted:insert(heap:heap_pop())
>> sorted == sorted:sorted()
= yes
diff --git a/test/iterators.tm b/test/iterators.tm
index 1f7ce342..0a2d2818 100644
--- a/test/iterators.tm
+++ b/test/iterators.tm
@@ -3,7 +3,7 @@ enum PairIteration(Done, Next(x:Text, y:Text))
func pairwise(strs:[Text])->func()->PairIteration:
i := 1
return func():
- if i + 1 > #strs: return PairIteration.Done
+ if i + 1 > strs.length: return PairIteration.Done
i += 1
return PairIteration.Next(strs[i-1], strs[i])
diff --git a/test/nums.tm b/test/nums.tm
index 94959744..48693f0e 100644
--- a/test/nums.tm
+++ b/test/nums.tm
@@ -37,9 +37,6 @@ func main():
>> Num.PI:sin():near(0)
= yes
- >> 10.0:pow(3)
- = 1000
-
>> Num.nan():near(Num.nan())
= no
diff --git a/test/tables.tm b/test/tables.tm
index 7f8383d8..7b3595b6 100644
--- a/test/tables.tm
+++ b/test/tables.tm
@@ -15,7 +15,7 @@ func main():
>> t_str
= "(one:1)(two:2)"
- >> #t
+ >> t.length
= 2
>> t.fallback
= !{Text:Int}
@@ -35,7 +35,7 @@ func main():
>> t2:get("???", 999)
= 999
- >> #t2
+ >> t2.length
= 1
>> t2.fallback
= @%{"one":1, "two":2}?
diff --git a/test/text.tm b/test/text.tm
index 2666b6c8..ce8ed43f 100644
--- a/test/text.tm
+++ b/test/text.tm
@@ -26,8 +26,6 @@ func main():
= [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
>> amelie:bytes()
= [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
- >> #amelie
- = 6
>> amelie:num_clusters()
= 6
>> amelie:num_codepoints()
@@ -42,8 +40,6 @@ func main():
= [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
>> amelie2:bytes()
= [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
- >> #amelie
- = 6
>> amelie2:num_clusters()
= 6
>> amelie2:num_codepoints()
diff --git a/typecheck.c b/typecheck.c
index b79b903c..739535c4 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -859,7 +859,6 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(AbortType);
}
case Pass: case Defer: return Type(VoidType);
- case Length: return INT_TYPE;
case Negative: {
ast_t *value = Match(ast, Negative)->value;
type_t *t = get_type(env, value);