summaryrefslogtreecommitdiffhomepage
path: root/compiler.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-11-29 23:09:28 +0100
committerGitHub <noreply@github.com>2022-11-29 23:09:28 +0100
commitcc8ae80fc0de0bf81c197e717e8523d621e9ec1f (patch)
tree0f9a074b8b4ebcb73b0487b4f2cce70ae9330857 /compiler.c
parent3497da1448f9b1d602e23c10977db0ce0188c959 (diff)
parenteac2add08377eb4ba8e43e7e6a8f385480ebd73b (diff)
Merge pull request #131 from jow-/fix-logical-assignment-operators-2
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c132
1 files changed, 68 insertions, 64 deletions
diff --git a/compiler.c b/compiler.c
index 6c336ae..6911477 100644
--- a/compiler.c
+++ b/compiler.c
@@ -575,6 +575,17 @@ uc_compiler_emit_jmp_dest(uc_compiler_t *compiler, size_t srcpos, uint32_t dest)
return chunk->count - 5;
}
+static size_t
+uc_compiler_emit_copy(uc_compiler_t *compiler, size_t srcpos, uint8_t depth)
+{
+ uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
+
+ uc_compiler_emit_insn(compiler, srcpos, I_COPY);
+ uc_compiler_emit_u8(compiler, 0, depth);
+
+ return chunk->count - 2;
+}
+
static ssize_t
uc_compiler_get_jmpaddr(uc_compiler_t *compiler, size_t off)
{
@@ -1153,93 +1164,104 @@ static void
uc_compiler_emit_variable_copy(uc_compiler_t *compiler, uc_value_t *var)
{
if (!var) {
- uc_compiler_emit_insn(compiler, 0, I_COPY);
- uc_compiler_emit_u8(compiler, 0, 1);
- uc_compiler_emit_insn(compiler, 0, I_COPY);
- uc_compiler_emit_u8(compiler, 0, 1);
+ uc_compiler_emit_copy(compiler, 0, 1);
+ uc_compiler_emit_copy(compiler, 0, 1);
}
uc_compiler_emit_variable_rw(compiler, var, 0);
}
static void
-uc_compiler_compile_and_common(uc_compiler_t *compiler, bool assignment, uc_value_t *var)
+uc_compiler_compile_and(uc_compiler_t *compiler)
{
uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
size_t jmpz_off;
- if (assignment)
- uc_compiler_emit_variable_copy(compiler, var);
-
- uc_compiler_emit_insn(compiler, 0, I_COPY);
- uc_compiler_emit_u8(compiler, 0, 0);
+ uc_compiler_emit_copy(compiler, 0, 0);
jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
uc_compiler_emit_insn(compiler, 0, I_POP);
+ uc_compiler_parse_precedence(compiler, P_AND);
+ uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
+}
- if (assignment) {
- uc_compiler_parse_precedence(compiler, P_ASSIGN);
- uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
- }
- else {
- uc_compiler_parse_precedence(compiler, P_AND);
- }
+static void
+uc_compiler_compile_and_assignment(uc_compiler_t *compiler, uc_value_t *var)
+{
+ uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
+ size_t jmpz_off;
+ uc_compiler_emit_variable_copy(compiler, var);
+ uc_compiler_emit_copy(compiler, 0, 0);
+ jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
+ uc_compiler_emit_insn(compiler, 0, I_POP);
+ uc_compiler_parse_precedence(compiler, P_ASSIGN);
uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
+ uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
}
static void
-uc_compiler_compile_or_common(uc_compiler_t *compiler, bool assignment, uc_value_t *var)
+uc_compiler_compile_or(uc_compiler_t *compiler)
{
uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
size_t jmpz_off, jmp_off;
- if (assignment)
- uc_compiler_emit_variable_copy(compiler, var);
-
- uc_compiler_emit_insn(compiler, 0, I_COPY);
- uc_compiler_emit_u8(compiler, 0, 0);
+ uc_compiler_emit_copy(compiler, 0, 0);
jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
jmp_off = uc_compiler_emit_jmp(compiler, 0);
uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
uc_compiler_emit_insn(compiler, 0, I_POP);
+ uc_compiler_parse_precedence(compiler, P_OR);
+ uc_compiler_set_jmpaddr(compiler, jmp_off, chunk->count);
+}
- if (assignment) {
- uc_compiler_parse_precedence(compiler, P_ASSIGN);
- uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
- }
- else {
- uc_compiler_parse_precedence(compiler, P_OR);
- }
+static void
+uc_compiler_compile_or_assignment(uc_compiler_t *compiler, uc_value_t *var)
+{
+ uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
+ size_t jmpz_off, jmp_off;
+ uc_compiler_emit_variable_copy(compiler, var);
+ jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
+ uc_compiler_emit_variable_rw(compiler, var, 0);
+ jmp_off = uc_compiler_emit_jmp(compiler, 0);
+ uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
+ uc_compiler_parse_precedence(compiler, P_ASSIGN);
+ uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
uc_compiler_set_jmpaddr(compiler, jmp_off, chunk->count);
}
static void
-uc_compiler_compile_nullish_common(uc_compiler_t *compiler, bool assignment, uc_value_t *var)
+uc_compiler_compile_nullish(uc_compiler_t *compiler)
{
uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
size_t jmpz_off, jmp_off;
- if (assignment)
- uc_compiler_emit_variable_copy(compiler, var);
-
- uc_compiler_emit_insn(compiler, 0, I_COPY);
- uc_compiler_emit_u8(compiler, 0, 0);
+ uc_compiler_emit_copy(compiler, 0, 0);
uc_compiler_emit_insn(compiler, 0, I_LNULL);
uc_compiler_emit_insn(compiler, 0, I_NES);
jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
jmp_off = uc_compiler_emit_jmp(compiler, 0);
uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
uc_compiler_emit_insn(compiler, 0, I_POP);
+ uc_compiler_parse_precedence(compiler, P_OR);
+ uc_compiler_set_jmpaddr(compiler, jmp_off, chunk->count);
+}
- if (assignment) {
- uc_compiler_parse_precedence(compiler, P_ASSIGN);
- uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
- }
- else {
- uc_compiler_parse_precedence(compiler, P_OR);
- }
+static void
+uc_compiler_compile_nullish_assignment(uc_compiler_t *compiler, uc_value_t *var)
+{
+ uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
+ size_t jmpz_off, jmp_off;
+ uc_compiler_emit_variable_copy(compiler, var);
+ uc_compiler_emit_insn(compiler, 0, I_LNULL);
+ uc_compiler_emit_insn(compiler, 0, I_NES);
+ jmpz_off = uc_compiler_emit_jmpz(compiler, 0);
+ uc_compiler_emit_variable_rw(compiler, var, 0);
+ jmp_off = uc_compiler_emit_jmp(compiler, 0);
+ uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
+ uc_compiler_parse_precedence(compiler, P_ASSIGN);
+ uc_compiler_emit_variable_rw(compiler, var, TK_ASSIGN);
uc_compiler_set_jmpaddr(compiler, jmp_off, chunk->count);
}
@@ -1256,19 +1278,19 @@ uc_compiler_compile_assignment(uc_compiler_t *compiler, uc_value_t *var)
if (type == TK_ASNULLISH) {
uc_compiler_parse_advance(compiler);
- uc_compiler_compile_nullish_common(compiler, true, var);
+ uc_compiler_compile_nullish_assignment(compiler, var);
return true;
}
else if (type == TK_ASOR) {
uc_compiler_parse_advance(compiler);
- uc_compiler_compile_or_common(compiler, true, var);
+ uc_compiler_compile_or_assignment(compiler, var);
return true;
}
else if (type == TK_ASAND) {
uc_compiler_parse_advance(compiler);
- uc_compiler_compile_and_common(compiler, true, var);
+ uc_compiler_compile_and_assignment(compiler, var);
return true;
}
@@ -1853,24 +1875,6 @@ uc_compiler_compile_funcdecl(uc_compiler_t *compiler)
}
static void
-uc_compiler_compile_and(uc_compiler_t *compiler)
-{
- return uc_compiler_compile_and_common(compiler, false, NULL);
-}
-
-static void
-uc_compiler_compile_or(uc_compiler_t *compiler)
-{
- return uc_compiler_compile_or_common(compiler, false, NULL);
-}
-
-static void
-uc_compiler_compile_nullish(uc_compiler_t *compiler)
-{
- return uc_compiler_compile_nullish_common(compiler, false, NULL);
-}
-
-static void
uc_compiler_compile_dot(uc_compiler_t *compiler)
{
bool optional_chaining = (compiler->parser->prev.type == TK_QDOT);