Add in '#' operator for length
This commit is contained in:
parent
733ebfd234
commit
eabff011ea
1
ast.c
1
ast.c
@ -94,6 +94,7 @@ CORD ast_to_cord(ast_t *ast)
|
||||
T(Assign, "(targets=%r, values=%r)", ast_list_to_cord(data.targets), ast_list_to_cord(data.values))
|
||||
T(BinaryOp, "(%r, %s, %r)", ast_to_cord(data.lhs), OP_NAMES[data.op], ast_to_cord(data.rhs))
|
||||
T(UpdateAssign, "(%r, %s, %r)", ast_to_cord(data.lhs), OP_NAMES[data.op], ast_to_cord(data.rhs))
|
||||
T(Length, "(%r)", ast_to_cord(data.value))
|
||||
T(Negative, "(%r)", ast_to_cord(data.value))
|
||||
T(Not, "(%r)", ast_to_cord(data.value))
|
||||
T(HeapAllocate, "(%r)", ast_to_cord(data.value))
|
||||
|
4
ast.h
4
ast.h
@ -88,7 +88,7 @@ typedef enum {
|
||||
StringLiteral, StringJoin,
|
||||
Declare, Assign,
|
||||
BinaryOp, UpdateAssign,
|
||||
Not, Negative, HeapAllocate, StackReference,
|
||||
Length, Not, Negative, HeapAllocate, StackReference,
|
||||
Min, Max,
|
||||
Array, Table, TableEntry,
|
||||
FunctionDef, Lambda,
|
||||
@ -150,7 +150,7 @@ struct ast_s {
|
||||
} BinaryOp, UpdateAssign;
|
||||
struct {
|
||||
ast_t *value;
|
||||
} Not, Negative, HeapAllocate, StackReference;
|
||||
} Length, Not, Negative, HeapAllocate, StackReference;
|
||||
struct {
|
||||
ast_t *lhs, *rhs, *key;
|
||||
} Min, Max;
|
||||
|
21
compile.c
21
compile.c
@ -75,6 +75,27 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
char *buf = asprintfa(Match(ast, Num)->bits == 64 ? "%a" : "%af", Match(ast, Num)->n);
|
||||
return CORD_from_char_star(buf);
|
||||
}
|
||||
case Length: {
|
||||
ast_t *expr = Match(ast, Length)->value;
|
||||
CORD code = compile(env, expr);
|
||||
type_t *t = get_type(env, expr);
|
||||
next_value:;
|
||||
switch (t->tag) {
|
||||
case PointerType: {
|
||||
auto ptr = Match(t, PointerType);
|
||||
if (ptr->is_optional)
|
||||
code_err(ast, "You can't dereference this value, since it's not guaranteed to be non-null");
|
||||
code = CORD_all("*(", code, ")");
|
||||
t = ptr->pointed;
|
||||
goto next_value;
|
||||
}
|
||||
case StringType: return CORD_all("CORD_len(", code, ")");
|
||||
case ArrayType: return CORD_all("I64((", code, ").length)");
|
||||
case TableType: return CORD_all("I64((", code, ").entries.length)");
|
||||
default: code_err(ast, "Length is only supported for strings, arrays, and tables, not: %T", t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Not: return CORD_asprintf("not(%r)", compile(env, Match(ast, Not)->value));
|
||||
case Negative: return CORD_asprintf("-(%r)", compile(env, Match(ast, Negative)->value));
|
||||
case HeapAllocate: return CORD_asprintf("$heap(%r)", compile(env, Match(ast, HeapAllocate)->value));
|
||||
|
9
parse.c
9
parse.c
@ -839,6 +839,14 @@ 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_expr, "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;
|
||||
@ -1070,6 +1078,7 @@ 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))
|
||||
|
@ -368,6 +368,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
return Type(AbortType);
|
||||
}
|
||||
case Pass: return Type(VoidType);
|
||||
case Length: return Type(IntType, .bits=64);
|
||||
case Negative: {
|
||||
type_t *t = get_type(env, Match(ast, Negative)->value);
|
||||
if (t->tag == IntType || t->tag == NumType)
|
||||
|
Loading…
Reference in New Issue
Block a user