Browse Source

parse changes, and operators == and !=

master
Martin Dørum 3 years ago
parent
commit
6ebc5345b3
5 changed files with 89 additions and 33 deletions
  1. 2
    0
      include/lang2/builtins.x.h
  2. 27
    31
      lib/parse/lex.c
  3. 3
    1
      lib/parse/parse.c
  4. 54
    0
      lib/vm/builtins.c
  5. 3
    1
      lib/vm/vm.c

+ 2
- 0
include/lang2/builtins.x.h View File

X("-", l2_builtin_sub) X("-", l2_builtin_sub)
X("*", l2_builtin_mul) X("*", l2_builtin_mul)
X("/", l2_builtin_div) X("/", l2_builtin_div)
X("==", l2_builtin_eq)
X("!=", l2_builtin_neq)
X("print", l2_builtin_print) X("print", l2_builtin_print)
X("len", l2_builtin_len) X("len", l2_builtin_len)
X("if", l2_builtin_if) X("if", l2_builtin_if)

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

return ch >= '0' && ch <= '9'; return ch >= '0' && ch <= '9';
} }


static int is_ident(int ch) {
return !is_whitespace(ch) && ch != EOF &&
ch != '(' && ch != ')' &&
ch != '{' && ch != '}' &&
ch != '[' && ch != ']' &&
ch != '\'' &&
ch != ',' && ch != '.' &&
ch != ':' && ch != ';';
}

static int skip_whitespace(struct l2_lexer *lexer) { static int skip_whitespace(struct l2_lexer *lexer) {
int nl = 0; int nl = 0;
while (1) { while (1) {
while (1) { while (1) {
int ch = peek_ch(lexer); int ch = peek_ch(lexer);


if (is_whitespace(ch)) {
dest[idx] = '\0';
return;
}

switch (ch) {
case '(':
case ')':
case '{':
case '}':
case '[':
case ']':
case '\'':
case ',':
case '.':
case ':':
case '=':
case ';':
case EOF:
if (!is_ident(ch)) {
dest[idx] = '\0'; dest[idx] = '\0';
return; return;
} }
} }
break; break;


case '=':
read_ch(lexer);
tok->v.flags = L2_TOK_EQUALS;
break;

case EOF: case EOF:
tok->v.flags = L2_TOK_EOF; tok->v.flags = L2_TOK_EOF;
break; break;
break; break;


default: default:
if (
is_numeric(ch) ||
(ch == '-' && is_numeric(peek_ch_n(lexer, 2)))) {
read_number(lexer, tok);
break;
}
{
int ch2 = peek_ch_n(lexer, 2);


read_ident(lexer, tok);
if (
is_numeric(ch) ||
(ch == '-' && is_numeric(ch2))) {
read_number(lexer, tok);
break;
}

tok->v.flags = L2_TOK_IDENT;
read_ident(lexer, tok);

if (l2_token_is_small(tok) && strcmp(tok->v.strbuf, "=") == 0) {
tok->v.flags = L2_TOK_EQUALS;
}
}
} }
} }



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

strcmp(str, "+") == 0 || strcmp(str, "+") == 0 ||
strcmp(str, "-") == 0 || strcmp(str, "-") == 0 ||
strcmp(str, "*") == 0 || strcmp(str, "*") == 0 ||
strcmp(str, "/") == 0;
strcmp(str, "/") == 0 ||
strcmp(str, "==") == 0 ||
strcmp(str, "!=") == 0;
} }


static int parse_expression( static int parse_expression(

+ 54
- 0
lib/vm/builtins.c View File

return id; return id;
} }


l2_word l2_builtin_eq(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 2) {
return vm->ktrue;
}

for (l2_word i = 1; i < argc; ++i) {
if (argv[i - 1] == argv[i]) continue;
struct l2_vm_value *a = &vm->values[argv[i - 1]];
struct l2_vm_value *b = &vm->values[argv[i]];
if (a->flags != b->flags) {
return vm->kfalse;
}

enum l2_value_type typ = l2_vm_value_type(a);
if (typ == L2_VAL_TYPE_ATOM) {
if (a->atom != b->atom) {
return vm->kfalse;
}
} else if (typ == L2_VAL_TYPE_REAL) {
if (a->real != b->real) {
return vm->kfalse;
}
} else if (typ == L2_VAL_TYPE_BUFFER) {
if (a->buffer == NULL && b->buffer == NULL) continue;
if (a->buffer == NULL || b->buffer == NULL) {
return vm->kfalse;
}

if (a->buffer->len != b->buffer->len) {
return vm->kfalse;
}

if (memcmp(a->buffer->data, b->buffer->data, a->buffer->len) != 0) {
return vm->kfalse;
}
} else {
return vm->kfalse;
}
}

return vm->ktrue;
}

l2_word l2_builtin_neq(struct l2_vm *vm, l2_word argc, l2_word *argv) {
l2_word ret_id = l2_builtin_eq(vm, argc, argv);
if (ret_id == vm->ktrue) {
return vm->kfalse;
} else if (ret_id == vm->kfalse) {
return vm->ktrue;
} else {
return ret_id;
}
}

l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) { l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (size_t i = 0; i < argc; ++i) { for (size_t i = 0; i < argc; ++i) {
if (i != 0) { if (i != 0) {

+ 3
- 1
lib/vm/vm.c View File

#define Y(name, k) \ #define Y(name, k) \
if (strcmp(#k, "knone") == 0) { \ if (strcmp(#k, "knone") == 0) { \
id = 0; \ id = 0; \
l2_vm_namespace_set(&vm->values[builtins], key, id); \
} else { \ } else { \
id = alloc_val(vm); \ id = alloc_val(vm); \
vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \
vm->values[id].atom = key; \ vm->values[id].atom = key; \
} \ } \
vm->k = id; \ vm->k = id; \
l2_vm_namespace_set(&vm->values[builtins], key++, id);
key += 1;
#define X(name, f) \ #define X(name, f) \
id = alloc_val(vm); \ id = alloc_val(vm); \
vm->values[id].flags = L2_VAL_TYPE_CFUNCTION | L2_VAL_CONST; \ vm->values[id].flags = L2_VAL_TYPE_CFUNCTION | L2_VAL_CONST; \
vm->values[id].cfunc = f; \ vm->values[id].cfunc = f; \
l2_vm_namespace_set(&vm->values[builtins], key++, id); l2_vm_namespace_set(&vm->values[builtins], key++, id);
#include "builtins.x.h" #include "builtins.x.h"
#undef Y
#undef X #undef X
} }



Loading…
Cancel
Save