Deprecate # operator in favor of .length and fix up some issues

This commit is contained in:
Bruce Hill 2024-08-18 20:39:57 -04:00
parent d804b09b02
commit 967b649da2
10 changed files with 23 additions and 61 deletions

1
ast.c
View File

@ -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))

4
ast.h
View File

@ -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;

View File

@ -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);
}

View File

@ -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))

View File

@ -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

View File

@ -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])

View File

@ -37,9 +37,6 @@ func main():
>> Num.PI:sin():near(0)
= yes
>> 10.0:pow(3)
= 1000
>> Num.nan():near(Num.nan())
= no

View File

@ -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}?

View File

@ -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()

View File

@ -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);