nandi/clonimpublic Fork
⑂ cfb27b8
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/clonim.git
git clone ssh://git@rickub.com/nandi/clonim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

feat: add mutable array compatibility primitives

nandithebull committed 2026-09-21T00:43:58-07:00 Browse files
cfb27b8 parent: 5757588
modified src/core.nim +24 -1
@@ -1,5 +1,5 @@
11 ## clonim core — clojure.core builtins, registered into the global var table.
2-import std/[strutils, math, times, random, re, os, httpclient]
2+import std/[strutils, math, times, random, re, os, httpclient, sequtils]
33 import runtime
44
55 proc num(v: Value): float64 =
@@ -544,6 +544,29 @@ proc registerCore*() =
544544 def "slurp", proc (a: openArray[Value]): Value = mkStr(readFile(a[0].s))
545545 def "spit", proc (a: openArray[Value]): Value =
546546 writeFile(a[0].s, str(a[1])); NilV
547+ def "int-array", proc (a: openArray[Value]): Value =
548+ if a.len == 1 and a[0].kind == kInt: mkList(newSeqWith(int(a[0].i), mkInt(0)))
549+ elif a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
550+ def "long-array", proc (a: openArray[Value]): Value =
551+ if a.len == 1 and a[0].kind == kInt: mkList(newSeqWith(int(a[0].i), mkInt(0)))
552+ elif a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
553+ def "byte-array", proc (a: openArray[Value]): Value =
554+ if a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
555+ def "alength", proc (a: openArray[Value]): Value = mkInt(count(a[0]))
556+ def "aget", proc (a: openArray[Value]): Value =
557+ let i = int(intOf(a[1]))
558+ if a[0].kind == kList: a[0].obj.xs[i] else: toSeq(a[0])[i]
559+ def "aset", proc (a: openArray[Value]): Value =
560+ if a[0].kind != kList: err("aset expects an array")
561+ a[0].obj.xs[int(intOf(a[1]))] = a[2]; a[2]
562+ def "System/arraycopy", proc (a: openArray[Value]): Value =
563+ for i in 0 ..< int(intOf(a[4])):
564+ a[2].obj.xs[int(intOf(a[3])) + i] = a[0].obj.xs[int(intOf(a[1])) + i]
565+ NilV
566+ def ".getBytes", proc (a: openArray[Value]): Value =
567+ var xs: seq[Value] = @[]
568+ for ch in a[0].s: xs.add mkInt(ord(ch))
569+ mkList(xs)
547570 def "*delete-file*", proc (a: openArray[Value]): Value =
548571 try:
549572 removeFile(a[0].s)
@@ -1,5 +1,5 @@
1 ## clonim core — clojure.core builtins, registered into the global var table.1 ## clonim core — clojure.core builtins, registered into the global var table.
2-import std/[strutils, math, times, random, re, os, httpclient]2+import std/[strutils, math, times, random, re, os, httpclient, sequtils]
3 import runtime3 import runtime
4 4
5 proc num(v: Value): float64 =5 proc num(v: Value): float64 =
@@ -544,6 +544,29 @@ proc registerCore*() =
544 def "slurp", proc (a: openArray[Value]): Value = mkStr(readFile(a[0].s))544 def "slurp", proc (a: openArray[Value]): Value = mkStr(readFile(a[0].s))
545 def "spit", proc (a: openArray[Value]): Value =545 def "spit", proc (a: openArray[Value]): Value =
546 writeFile(a[0].s, str(a[1])); NilV546 writeFile(a[0].s, str(a[1])); NilV
547+ def "int-array", proc (a: openArray[Value]): Value =
548+ if a.len == 1 and a[0].kind == kInt: mkList(newSeqWith(int(a[0].i), mkInt(0)))
549+ elif a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
550+ def "long-array", proc (a: openArray[Value]): Value =
551+ if a.len == 1 and a[0].kind == kInt: mkList(newSeqWith(int(a[0].i), mkInt(0)))
552+ elif a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
553+ def "byte-array", proc (a: openArray[Value]): Value =
554+ if a.len == 1: mkList(toSeq(a[0])) else: mkList(a)
555+ def "alength", proc (a: openArray[Value]): Value = mkInt(count(a[0]))
556+ def "aget", proc (a: openArray[Value]): Value =
557+ let i = int(intOf(a[1]))
558+ if a[0].kind == kList: a[0].obj.xs[i] else: toSeq(a[0])[i]
559+ def "aset", proc (a: openArray[Value]): Value =
560+ if a[0].kind != kList: err("aset expects an array")
561+ a[0].obj.xs[int(intOf(a[1]))] = a[2]; a[2]
562+ def "System/arraycopy", proc (a: openArray[Value]): Value =
563+ for i in 0 ..< int(intOf(a[4])):
564+ a[2].obj.xs[int(intOf(a[3])) + i] = a[0].obj.xs[int(intOf(a[1])) + i]
565+ NilV
566+ def ".getBytes", proc (a: openArray[Value]): Value =
567+ var xs: seq[Value] = @[]
568+ for ch in a[0].s: xs.add mkInt(ord(ch))
569+ mkList(xs)
547 def "*delete-file*", proc (a: openArray[Value]): Value =570 def "*delete-file*", proc (a: openArray[Value]): Value =
548 try:571 try:
549 removeFile(a[0].s)572 removeFile(a[0].s)
modified src/namespaces.nim +2 -1
@@ -99,9 +99,10 @@ proc checkVar(r: Resolver, ns: Namespace, target, name: string,
9999 if target == "clojure.core":
100100 if name in r.cores or (allowSyntax and name in syntaxHeads): return
101101 fail("no definition " & canonical)
102+ # JVM-style host calls (for example System/arraycopy) are globally provided.
103+ if canonical in r.hosts: return
102104 if target != ns.name and target notin ns.required:
103105 fail("namespace " & target & " is not required by " & ns.name)
104- if canonical in r.hosts: return
105106 if not r.spaces.hasKey(target) or name notin r.spaces[target].defs:
106107 fail("no definition " & canonical)
107108 if target != ns.name and name in r.spaces[target].privateDefs:
@@ -99,9 +99,10 @@ proc checkVar(r: Resolver, ns: Namespace, target, name: string,
99 if target == "clojure.core":99 if target == "clojure.core":
100 if name in r.cores or (allowSyntax and name in syntaxHeads): return100 if name in r.cores or (allowSyntax and name in syntaxHeads): return
101 fail("no definition " & canonical)101 fail("no definition " & canonical)
102+ # JVM-style host calls (for example System/arraycopy) are globally provided.
103+ if canonical in r.hosts: return
102 if target != ns.name and target notin ns.required:104 if target != ns.name and target notin ns.required:
103 fail("namespace " & target & " is not required by " & ns.name)105 fail("namespace " & target & " is not required by " & ns.name)
104- if canonical in r.hosts: return
105 if not r.spaces.hasKey(target) or name notin r.spaces[target].defs:106 if not r.spaces.hasKey(target) or name notin r.spaces[target].defs:
106 fail("no definition " & canonical)107 fail("no definition " & canonical)
107 if target != ns.name and name in r.spaces[target].privateDefs:108 if target != ns.name and name in r.spaces[target].privateDefs: