Static array kinda works now.

This commit is contained in:
Erik Svedäng 2020-04-28 10:06:17 +02:00
parent 98d4538efc
commit 14b608a36e
7 changed files with 439 additions and 4 deletions

View File

@ -35,6 +35,7 @@
(load "Double.carp")
(load "Float.carp")
(load "Tuples.carp")
(load "StaticArray.carp")
(load "Array.carp")
(load "Char.carp")
(load "String.carp")

30
core/StaticArray.carp Normal file
View File

@ -0,0 +1,30 @@
(defmodule StaticArray
(defndynamic foreach-internal [var xs expr]
(let [xsym (gensym-with 'xs)
len (gensym-with 'len)
i (gensym-with 'i)]
(list 'let [xsym xs
len (list 'StaticArray.length xsym)]
(list 'for [i 0 len]
(list 'let [var (list 'StaticArray.unsafe-nth xsym i)]
expr)))))
;; NOTE: Exact copy of the Array.foreach macro, could be made "generic" by removing the module prefixes.
(defmacro foreach [binding expr]
(StaticArray.foreach-internal (car binding) (cadr binding) expr))
(doc map! "Maps a function over the static array `xs`, mutating it in place. The difference to Array.endo-map (which does the same thing internally) is that this function takes a ref (since you can never have static arrays as values) and that it returns ().")
(defn map! [xs f]
(for [i 0 (StaticArray.length xs)]
(StaticArray.aset! xs i (~f (StaticArray.unsafe-nth xs i)))))
;; NOTE: Exact copy of the Array.reduce function.
(defn reduce [f x xs]
(let [total x]
(do
(for [i 0 (StaticArray.length xs)]
(set! total (~f total (StaticArray.unsafe-nth xs i))))
total)))
)

338
docs/core/StaticArray.html Normal file
View File

@ -0,0 +1,338 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="carp_style.css">
</head>
<body>
<div class="content">
<div class="logo">
<a href="http://github.com/carp-lang/Carp">
<img src="logo.png">
</a>
<div class="title">
core
</div>
<div class="index">
<ul>
<li>
<a href="Dynamic.html">
Dynamic
</a>
</li>
<li>
<a href="Int.html">
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long
</a>
</li>
<li>
<a href="Bool.html">
Bool
</a>
</li>
<li>
<a href="Float.html">
Float
</a>
</li>
<li>
<a href="Double.html">
Double
</a>
</li>
<li>
<a href="Vector2.html">
Vector2
</a>
</li>
<li>
<a href="Vector3.html">
Vector3
</a>
</li>
<li>
<a href="VectorN.html">
VectorN
</a>
</li>
<li>
<a href="Geometry.html">
Geometry
</a>
</li>
<li>
<a href="Statistics.html">
Statistics
</a>
</li>
<li>
<a href="String.html">
String
</a>
</li>
<li>
<a href="Char.html">
Char
</a>
</li>
<li>
<a href="Pattern.html">
Pattern
</a>
</li>
<li>
<a href="Array.html">
Array
</a>
</li>
<li>
<a href="StaticArray.html">
StaticArray
</a>
</li>
<li>
<a href="IO.html">
IO
</a>
</li>
<li>
<a href="System.html">
System
</a>
</li>
<li>
<a href="Debug.html">
Debug
</a>
</li>
<li>
<a href="Test.html">
Test
</a>
</li>
<li>
<a href="Bench.html">
Bench
</a>
</li>
<li>
<a href="Map.html">
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>
<h1>
StaticArray
</h1>
<div class="module-description">
</div>
<div class="binder">
<a class="anchor" href="#aset!">
<h3 id="aset!">
aset!
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (StaticArray a) b), Int, a] ())
</p>
<span>
</span>
<p class="doc">
<p>sets an array element at the index <code>n</code> to a new value in place.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#delete">
<h3 id="delete">
delete
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(StaticArray a)] ())
</p>
<span>
</span>
<p class="doc">
<p>deletes a static array. This function should not be called manually (there shouldn't be a way to create value types of type StaticArray).</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#foreach">
<h3 id="foreach">
foreach
</h3>
</a>
<div class="description">
macro
</div>
<p class="sig">
Macro
</p>
<pre class="args">
(foreach binding expr)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#foreach-internal">
<h3 id="foreach-internal">
foreach-internal
</h3>
</a>
<div class="description">
dynamic
</div>
<p class="sig">
Dynamic
</p>
<pre class="args">
(foreach-internal var xs expr)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#length">
<h3 id="length">
length
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (StaticArray a) b)] Int)
</p>
<span>
</span>
<p class="doc">
<p>gets the length of the static array.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#map!">
<h3 id="map!">
map!
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (StaticArray a) b), (Ref (λ [(Ref a b)] a c) d)] ())
</p>
<pre class="args">
(map! xs f)
</pre>
<p class="doc">
<p>Maps a function over the static array <code>xs</code>, mutating it in place. The difference to Array.endo-map (which does the same thing internally) is that this function takes a ref (since you can never have static arrays as values) and that it returns ().</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#reduce">
<h3 id="reduce">
reduce
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (λ [a, (Ref b c)] a d) e), a, (Ref (StaticArray b) c)] a)
</p>
<pre class="args">
(reduce f x xs)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#str">
<h3 id="str">
str
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (StaticArray a) b)] String)
</p>
<span>
</span>
<p class="doc">
<p>converts a static array to a string.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-nth">
<h3 id="unsafe-nth">
unsafe-nth
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (StaticArray a) b), Int] (Ref a b))
</p>
<span>
</span>
<p class="doc">
<p>gets a reference to the <code>n</code>th element from a static array <code>a</code>.</p>
</p>
</div>
</div>
</body>
</html>

View File

@ -1,4 +1,6 @@
(defn main []
(Debug.memory-logged
(let [xs $[@"a" @"b" @"c"]]
(println* (StaticArray.unsafe-nth xs 2)))))
(let [xs $[1 2 3 4 5]]
(do
(StaticArray.map! xs &(fn [x] (+ @x 1)))
(println* (StaticArray.reduce &(fn [total x] (+ total @x)) 0 xs))))))

View File

@ -431,7 +431,7 @@ templateStrArray = defineTypeParameterizedTemplate templateCreator path t docs
-- | TODO: move this into the templateStrArray function?
strTy :: TypeEnv -> Env -> Ty -> [Token]
strTy typeEnv env (StructTy "Array" [innerType]) =
strTy typeEnv env (StructTy _ [innerType]) =
[ TokC ""
, TokC " String temp = NULL;\n"
, TokC $ calculateStrSize typeEnv env innerType

View File

@ -14,6 +14,7 @@ import Commands
import Parsing
import Eval
import Concretize
import Debug.Trace (trace)
-- | These modules will be loaded in order before any other code is evaluated.
coreModules :: String -> [String]
@ -57,6 +58,8 @@ staticArrayModule = Env { envBindings = bindings
where bindings = Map.fromList [ StaticArray.templateUnsafeNth
, StaticArray.templateLength
, StaticArray.templateDeleteArray
, StaticArray.templateAsetBang
, StaticArray.templateStrArray
]
-- | The Pointer module contains functions for dealing with pointers.
@ -461,7 +464,7 @@ startingTypeEnv = Env { envBindings = bindings
builtInSymbolInfo
, interfaceBinder "str" (FuncTy [VarTy "a"] StringTy StaticLifetimeTy)
(SymPath ["Array"] "str" : registerFunctionFunctionsWithInterface "str")
((SymPath ["Array"] "str") : (SymPath ["StaticArray"] "str") : registerFunctionFunctionsWithInterface "str")
builtInSymbolInfo
, interfaceBinder "prn" (FuncTy [VarTy "a"] StringTy StaticLifetimeTy)

View File

@ -66,3 +66,64 @@ deleteTy typeEnv env (StructTy _ [innerType]) =
, TokC " }\n"
]
deleteTy _ _ _ = []
-- templateEMap :: (String, Binder)
-- templateEMap =
-- let fTy = FuncTy [VarTy "a"] (VarTy "a") (VarTy "fq")
-- aTy = RefTy (StructTy "StaticArray" [VarTy "a"]) (VarTy "q")
-- bTy = RefTy (StructTy "StaticArray" [VarTy "a"]) (VarTy "q")
-- elem = "((($a*)a.data)[i])"
-- in defineTemplate
-- (SymPath ["StaticArray"] "endo-map")
-- (FuncTy [RefTy fTy (VarTy "q"), aTy] bTy StaticLifetimeTy)
-- "applies a function `f` to an array `a`. The type of the elements cannot change."
-- (toTemplate "Array $NAME(Lambda *f, Array a)") -- Lambda used to be $(Fn [a] a)
-- (toTemplate $ unlines
-- ["$DECL { "
-- ," for(int i = 0; i < a.len; ++i) {"
-- ," (($a*)a.data)[i] = " ++ templateCodeForCallingLambda "(*f)" fTy [elem] ++ ";"
-- ," }"
-- ," return a;"
-- ,"}"
-- ])
-- (\(FuncTy [RefTy t@(FuncTy fArgTys fRetTy _) _, arrayType] _ _) ->
-- [defineFunctionTypeAlias t, defineFunctionTypeAlias (FuncTy (lambdaEnvTy : fArgTys) fRetTy StaticLifetimeTy)])
templateAsetBang :: (String, Binder)
templateAsetBang = defineTypeParameterizedTemplate templateCreator path t docs
where path = SymPath ["StaticArray"] "aset!"
t = FuncTy [RefTy (StructTy "StaticArray" [VarTy "t"]) (VarTy "q"), IntTy, VarTy "t"] UnitTy StaticLifetimeTy
docs = "sets an array element at the index `n` to a new value in place."
templateCreator = TemplateCreator $
\typeEnv env ->
Template
t
(const (toTemplate "void $NAME (Array *aRef, int n, $t newValue)"))
(\(FuncTy [_, _, insideTy] _ _) ->
let deleter = ArrayTemplates.insideArrayDeletion typeEnv env insideTy
in (toTemplate $ unlines ["$DECL {"
," Array a = *aRef;"
," assert(n >= 0);"
," assert(n < a.len);"
, deleter "n"
," (($t*)a.data)[n] = newValue;"
,"}"]))
(\(FuncTy [RefTy arrayType _, _, _] _ _) ->
depsForDeleteFunc typeEnv env arrayType)
templateStrArray :: (String, Binder)
templateStrArray = defineTypeParameterizedTemplate templateCreator path t docs
where templateCreator = TemplateCreator $
\typeEnv env ->
Template
t
(const (toTemplate "String $NAME (Array* a)"))
(\(FuncTy [RefTy arrayType _] StringTy _) ->
[TokDecl, TokC " {\n"] ++
ArrayTemplates.strTy typeEnv env arrayType ++
[TokC "}\n"])
(\(FuncTy [RefTy arrayType@(StructTy "StaticArray" [insideType]) _] StringTy _) ->
depsForPrnFunc typeEnv env insideType)
path = SymPath ["StaticArray"] "str"
t = FuncTy [RefTy (StructTy "StaticArray" [VarTy "a"]) (VarTy "q")] StringTy StaticLifetimeTy
docs = "converts a static array to a string."