Browse Source

array lookup with a dot-number token

master
Martin Dørum 3 years ago
parent
commit
fb5a02c602
8 changed files with 80 additions and 4 deletions
  1. 9
    1
      include/lang2/bytecode.h
  2. 1
    0
      include/lang2/gen/gen.h
  3. 2
    0
      include/lang2/parse/lex.h
  4. 6
    0
      lib/gen/gen.c
  5. 31
    2
      lib/parse/lex.c
  6. 14
    1
      lib/parse/parse.c
  7. 8
    0
      lib/vm/print.c
  8. 9
    0
      lib/vm/vm.c

+ 9
- 1
include/lang2/bytecode.h View File

L2_OP_NAMESPACE_SET, L2_OP_NAMESPACE_SET,


/* /*
* Set a namespace's name to a value.
* Lookup a value from a namespace.
* Pop <key> * Pop <key>
* Pop <ns> * Pop <ns>
* Push <ns[<key>]> * Push <ns[<key>]>
*/ */
L2_OP_NAMESPACE_LOOKUP, L2_OP_NAMESPACE_LOOKUP,


/*
* Look up a value from an array.
* Pop <key>
* Pop <arr>
* Push <arr[<key>]>
*/
L2_OP_DIRECT_ARRAY_LOOKUP,

/* /*
* Halt execution. * Halt execution.
*/ */

+ 1
- 0
include/lang2/gen/gen.h View File

void l2_gen_namespace(struct l2_generator *gen); void l2_gen_namespace(struct l2_generator *gen);
void l2_gen_namespace_set(struct l2_generator *gen, char **ident); void l2_gen_namespace_set(struct l2_generator *gen, char **ident);
void l2_gen_namespace_lookup(struct l2_generator *gen, char **ident); void l2_gen_namespace_lookup(struct l2_generator *gen, char **ident);
void l2_gen_direct_array_lookup(struct l2_generator *gen, int number);
void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident); void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident);
void l2_gen_func_call(struct l2_generator *gen); void l2_gen_func_call(struct l2_generator *gen);



+ 2
- 0
include/lang2/parse/lex.h View File

L2_TOK_QUOT, L2_TOK_QUOT,
L2_TOK_COMMA, L2_TOK_COMMA,
L2_TOK_PERIOD, L2_TOK_PERIOD,
L2_TOK_DOT_NUMBER,
L2_TOK_COLON, L2_TOK_COLON,
L2_TOK_COLON_EQ, L2_TOK_COLON_EQ,
L2_TOK_EOL, L2_TOK_EOL,
union { union {
char *str; char *str;
double num; double num;
int integer;
} v; } v;
}; };



+ 6
- 0
lib/gen/gen.c View File

put(gen, L2_OP_NAMESPACE_LOOKUP); put(gen, L2_OP_NAMESPACE_LOOKUP);
} }


void l2_gen_direct_array_lookup(struct l2_generator *gen, int number) {
put(gen, L2_OP_PUSH);
put(gen, number);
put(gen, L2_OP_DIRECT_ARRAY_LOOKUP);
}

void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident) { void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident) {
size_t atom_id = l2_strset_put(&gen->atomset, ident); size_t atom_id = l2_strset_put(&gen->atomset, ident);
put(gen, L2_OP_PUSH); put(gen, L2_OP_PUSH);

+ 31
- 2
lib/parse/lex.c View File

return "comma"; return "comma";
case L2_TOK_PERIOD: case L2_TOK_PERIOD:
return "period"; return "period";
case L2_TOK_DOT_NUMBER:
return "dot-number";
case L2_TOK_COLON: case L2_TOK_COLON:
return "colon"; return "colon";
case L2_TOK_COLON_EQ: case L2_TOK_COLON_EQ:
return ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t'; return ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t';
} }


static int is_numeric(int ch) {
return ch >= '0' && ch <= '9';
}

static int skip_whitespace(struct l2_lexer *lexer) { static int skip_whitespace(struct l2_lexer *lexer) {
int nl = 0; int nl = 0;
while (is_whitespace(l2_bufio_peek(&lexer->reader, 1))) {
while (is_whitespace(peek_ch(lexer))) {
int ch = read_ch(lexer); int ch = read_ch(lexer);
if (ch == '\n') { if (ch == '\n') {
nl = 1; nl = 1;
return nl; return nl;
} }


static int read_integer(struct l2_lexer *lexer) {
char buffer[16]; // Should be enough
int len = 0;

while (len < sizeof(buffer) - 1 && is_numeric(peek_ch(lexer))) {
buffer[len++] = read_ch(lexer);
}

int num = 0;
int power = 1;
for (int i = len - 1; i >= 0; --i) {
num += (buffer[i] - '0') * power;
power *= 10;
}

return num;
}

static void read_string(struct l2_lexer *lexer, struct l2_token *tok) { static void read_string(struct l2_lexer *lexer, struct l2_token *tok) {
tok->kind = L2_TOK_STRING; tok->kind = L2_TOK_STRING;
tok->v.str = malloc(16); tok->v.str = malloc(16);


case '.': case '.':
read_ch(lexer); read_ch(lexer);
tok->kind = L2_TOK_PERIOD;
if (is_numeric(peek_ch(lexer))) {
tok->kind = L2_TOK_DOT_NUMBER;
tok->v.integer = read_integer(lexer);
} else {
tok->kind = L2_TOK_PERIOD;
}
break; break;


case ':': case ':':

+ 14
- 1
lib/parse/parse.c View File

l2_trace_scope("function literal"); l2_trace_scope("function literal");
// '{' and EOL already skipped by parse_object_or_function_literal // '{' and EOL already skipped by parse_object_or_function_literal


// The arguments array will be at the top of the stack
char *ident = malloc(2);
ident[0] = '$'; ident[1] = '\0';
l2_gen_assignment(gen, &ident);

int first = 1; int first = 1;
while (1) { while (1) {
if (l2_lexer_peek(lexer, 1)->kind == L2_TOK_CLOSE_BRACE) { if (l2_lexer_peek(lexer, 1)->kind == L2_TOK_CLOSE_BRACE) {
l2_token_kind_name(tok->kind)); l2_token_kind_name(tok->kind));
return -1; return -1;
} }

l2_lexer_consume(lexer); // ')'
} else if (tok->kind == L2_TOK_IDENT) { } else if (tok->kind == L2_TOK_IDENT) {
l2_trace_scope("ident"); l2_trace_scope("ident");
l2_trace("ident '%s'", tok->v.str); l2_trace("ident '%s'", tok->v.str);
l2_gen_push(gen, 0); l2_gen_push(gen, 0);
l2_gen_func_call(gen); l2_gen_func_call(gen);
} else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) { } else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("lookup");
l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str); l2_trace("ident '%s'", tok2->v.str);
char *ident = l2_token_extract_str(tok2); char *ident = l2_token_extract_str(tok2);
l2_lexer_consume(lexer); // '.' l2_lexer_consume(lexer); // '.'
l2_lexer_consume(lexer); // ident l2_lexer_consume(lexer); // ident


l2_gen_namespace_lookup(gen, &ident); l2_gen_namespace_lookup(gen, &ident);
} else if (tok->kind == L2_TOK_DOT_NUMBER) {
l2_trace_scope("direct array lookup");
int number = tok->v.integer;
l2_lexer_consume(lexer); // dot-number

l2_gen_direct_array_lookup(gen, number);
} else { } else {
break; break;
} }

+ 8
- 0
lib/vm/print.c View File

printf("NAMESPACE_SET\n"); printf("NAMESPACE_SET\n");
break; break;


case L2_OP_NAMESPACE_LOOKUP:
printf("NAMESPACE_LOOKUP\n");
break;

case L2_OP_DIRECT_ARRAY_LOOKUP:
printf("DIRECT_ARRAY_LOOKUP\n");
break;

case L2_OP_HALT: case L2_OP_HALT:
printf("HALT\n"); printf("HALT\n");
break; break;

+ 9
- 0
lib/vm/vm.c View File

} }
break; break;


case L2_OP_DIRECT_ARRAY_LOOKUP:
{
l2_word key = vm->stack[--vm->sptr];
l2_word arr = vm->stack[--vm->sptr];
// TODO: Error if out of bounds or incorrect type
vm->stack[vm->sptr++] = vm->values[arr].array->data[key];
break;
}

case L2_OP_HALT: case L2_OP_HALT:
break; break;
} }

Loading…
Cancel
Save