]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add array constructors
authorfennecdjay <fennecdjay@gmail.com>
Tue, 9 Aug 2022 02:17:50 +0000 (04:17 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Tue, 9 Aug 2022 02:19:17 +0000 (04:19 +0200)
ast
fmt
src/lib/array.c

diff --git a/ast b/ast
index fc67c20c24ce0c11dffa810261cc7ca35f979a43..d209401af10f46516613b71cccd91ebc01ebd28c 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit fc67c20c24ce0c11dffa810261cc7ca35f979a43
+Subproject commit d209401af10f46516613b71cccd91ebc01ebd28c
diff --git a/fmt b/fmt
index c4f7d942d21cf1f5ebc7f39a1e870f0e3c2d1b36..7677470e7793b67ff988630c8d2204271c74e14f 160000 (submodule)
--- a/fmt
+++ b/fmt
@@ -1 +1 @@
-Subproject commit c4f7d942d21cf1f5ebc7f39a1e870f0e3c2d1b36
+Subproject commit 7677470e7793b67ff988630c8d2204271c74e14f
index 00ef4d0886be632c3fe00eaf455cedc53cc564ec..acf06cdfbacd9ccf355aeb5efa0e36e4db75c109 100644 (file)
@@ -411,6 +411,10 @@ static m_bit                 foldr_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ foldr_run_code = {.name     = "foldr_run_code",
                                                .bytecode = foldr_byte};
 
+static m_bit                 new_byte[BYTECODE_SZ * 5];
+static const struct VM_Code_ new_run_code = {.name     = "new_run_code",
+                                             .bytecode = new_byte};
+
 typedef struct FunctionalFrame {
   VM_Code  code;
   M_Object o;
@@ -627,6 +631,35 @@ static INSTR(fold_run_end) {
   _finish(shred, frame);
 }
 
+static INSTR(new_run_ini) {
+  const m_uint offset = *(m_uint *)REG(SZ_INT);
+  if (offset) PUSH_MEM(shred, offset);
+  const M_Object arg  = *(M_Object *)MEM(SZ_INT);
+  const VM_Code code = *(VM_Code*)arg->data;
+  *(VM_Code*)REG(0)  = code;
+  PUSH_REG(shred, SZ_INT);
+  FunctionalFrame *frame = &*(FunctionalFrame *)MEM(SZ_INT * 3);
+  shred->pc++;
+  shred->mem += MAP_CODE_OFFSET + SZ_INT; // work in a safe memory space
+  *(m_uint*)MEM(SZ_INT*2+offset)  = frame->index;
+}
+
+static INSTR(new_run_end) {
+  shred->mem -= MAP_CODE_OFFSET + SZ_INT;
+  FunctionalFrame *const frame   = &*(FunctionalFrame *)MEM(SZ_INT * 3);
+  const M_Object   self    = *(M_Object *)MEM(0);
+  const M_Vector   array = ARRAY(self);
+  const m_uint     base_sz = ARRAY_SIZE(array);
+  m_vector_set(array, frame->index,  REG(-base_sz));
+  POP_REG(shred, base_sz);
+  if (++frame->index == ARRAY_LEN(ARRAY(self))) {
+    shred->pc   = frame->pc;
+    shred->code = frame->code;
+    *(M_Object*)REG(-SZ_INT) = self;
+  } else _next(shred, frame->offset);
+  _finish(shred, frame);
+}
+
 static MFUN(vm_vector_foldl) {
   const m_bit *byte   = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ;
   const m_uint acc_sz = *(m_uint *)(byte + SZ_INT);
@@ -651,7 +684,14 @@ static MFUN(vm_vector_foldr) {
     memcpy((m_bit *)RETURN, MEM(SZ_INT * 2), acc_sz);
 }
 
-#include "template.h"
+static MFUN(vm_vector_new) {
+  if (ARRAY_LEN(ARRAY(o))) {
+    const m_uint   offset = *(m_uint *)REG(SZ_INT * 3);
+    _init(shred, &new_run_code, *(M_Object*)MEM(SZ_INT*1), offset, SZ_INT);
+  }
+  *(M_Object *)RETURN = o;
+}
+
 static void array_func(const Env env, const Type t, const m_str name, f_xfun fun) {
   const Value v = nspc_lookup_value0(t->nspc, insert_symbol(name));
   builtin_func(env->gwion, v->d.func_ref, fun);
@@ -729,6 +769,7 @@ static OP_CHECK(opck_array_scan) {
   array_func(env, t, "count", vm_vector_count);
   array_func(env, t, "foldl", vm_vector_foldl);
   array_func(env, t, "foldr", vm_vector_foldr);
+//  array_func(env, t, "new", vm_vector_new);
 
   if (isa(base, env->gwion->type[et_compound]) > 0) {
     t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, NULL,
@@ -821,6 +862,8 @@ GWION_IMPORT(array) {
   prepare_map_run(count_byte, count_run_end);
   prepare_fold_run(foldl_byte, foldl_run_ini);
   prepare_fold_run(foldr_byte, foldr_run_ini);
+  prepare_run(new_byte, new_run_ini, new_run_end);
+  vm_prepare(NULL, new_byte);
   const Type t_array = gwi_class_ini(gwi, "Array:[T]", "Object");
   set_tflag(t_array, tflag_infer);
   gwi->gwion->type[et_array] = t_array;
@@ -844,6 +887,10 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_func_arg(gwi, "T", "elem"))
   GWI_BB(gwi_fptr_end(gwi, ae_flag_static))
 
+  GWI_BB(gwi_fptr_ini(gwi, "T", "new_t"))
+  GWI_BB(gwi_func_arg(gwi, "int", "idx"))
+  GWI_BB(gwi_fptr_end(gwi, ae_flag_static))
+
   // put functions using T first
   GWI_BB(gwi_func_ini(gwi, "bool", "remove"))
   GWI_BB(gwi_func_arg(gwi, "int", "index"))
@@ -891,6 +938,10 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_func_arg(gwi, "A", "initial"))
   GWI_BB(gwi_func_end(gwi, vm_vector_foldr, ae_flag_none))
 
+  GWI_BB(gwi_func_ini(gwi, "auto", "new"))
+  GWI_BB(gwi_func_arg(gwi, "new_t", "init"))
+  GWI_BB(gwi_func_end(gwi, vm_vector_new, ae_flag_none))
+
   GWI_BB(gwi_class_end(gwi))
 
   GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))