Merge pull request #608 from hellerve/pointer-arith

Add pointer arithmetic
This commit is contained in:
Erik Svedäng 2019-11-25 12:36:10 +01:00 committed by GitHub
commit cf276f4488
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 573 additions and 1 deletions

View File

@ -35,6 +35,7 @@
(load "System.carp")
(load "Pattern.carp")
(load "Debug.carp")
(load "Pointer.carp")
(load "Format.carp")
(load "Random.carp")
(load "Map.carp")

4
core/Pointer.carp Normal file
View File

@ -0,0 +1,4 @@
(defmodule Pointer
(defn inc [a] (Pointer.add a 1l))
(defn dec [a] (Pointer.sub a 1l))
)

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

349
docs/core/Pointer.html Normal file
View File

@ -0,0 +1,349 @@
<!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="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="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>
Pointer
</h1>
<div class="module-description">
</div>
<div class="binder">
<a class="anchor" href="#add">
<h3 id="add">
add
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p), Long] (Ptr p))
</p>
<span>
</span>
<p class="doc">
<p>adds a long integer value to a pointer.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#copy">
<h3 id="copy">
copy
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Ptr p))] (Ptr p))
</p>
<span>
</span>
<p class="doc">
<p>copies a pointer <code>p</code>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#dec">
<h3 id="dec">
dec
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ptr a)] (Ptr a))
</p>
<pre class="args">
(dec a)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#eq">
<h3 id="eq">
eq
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p), (Ptr p)] Bool)
</p>
<span>
</span>
<p class="doc">
<p>checks two pointers for equality.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#from-long">
<h3 id="from-long">
from-long
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [Long] (Ptr p))
</p>
<span>
</span>
<p class="doc">
<p>converts a long integer to a pointer.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#inc">
<h3 id="inc">
inc
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ptr a)] (Ptr a))
</p>
<pre class="args">
(inc a)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#sub">
<h3 id="sub">
sub
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p), Long] (Ptr p))
</p>
<span>
</span>
<p class="doc">
<p>subtracts a long integer value from a pointer.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#to-long">
<h3 id="to-long">
to-long
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p)] Long)
</p>
<span>
</span>
<p class="doc">
<p>converts a pointer to a long integer.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#to-ref">
<h3 id="to-ref">
to-ref
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p)] &amp;p)
</p>
<span>
</span>
<p class="doc">
<p>converts a pointer to a reference type. The user will have to ensure themselves that this is a safe operation.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#width">
<h3 id="width">
width
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ptr p)] Long)
</p>
<span>
</span>
<p class="doc">
<p>gets the byte size of a pointer.</p>
</p>
</div>
</div>
</body>
</html>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -132,6 +132,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -128,6 +128,11 @@
Result
</a>
</li>
<li>
<a href="Pointer.html">
Pointer
</a>
</li>
</ul>
</div>
</div>

View File

@ -34,6 +34,7 @@
Map
Maybe
Result
Pointer
)
(quit)

View File

@ -52,7 +52,15 @@ pointerModule = Env { envBindings = bindings
, envUseModules = []
, envMode = ExternalEnv
, envFunctionNestingLevel = 0 }
where bindings = Map.fromList [ templatePointerCopy, templatePointerEqual, templatePointerToRef ]
where bindings = Map.fromList [ templatePointerCopy
, templatePointerEqual
, templatePointerToRef
, templatePointerAdd
, templatePointerSub
, templatePointerWidth
, templatePointerToLong
, templatePointerFromLong
]
-- | A template function for copying (= deref:ing) any pointer.
templatePointerCopy :: (String, Binder)
@ -87,6 +95,56 @@ templatePointerToRef = defineTemplate
,"}"])
(const [])
templatePointerAdd = defineTemplate
(SymPath ["Pointer"] "add")
(FuncTy [PointerTy (VarTy "p"), LongTy] (PointerTy (VarTy "p")))
"adds a long integer value to a pointer."
(toTemplate "$p* $NAME ($p *p, long x)")
(toTemplate $ unlines ["$DECL {"
," return p + x;"
,"}"])
(const [])
templatePointerSub = defineTemplate
(SymPath ["Pointer"] "sub")
(FuncTy [PointerTy (VarTy "p"), LongTy] (PointerTy (VarTy "p")))
"subtracts a long integer value from a pointer."
(toTemplate "$p* $NAME ($p *p, long x)")
(toTemplate $ unlines ["$DECL {"
," return p - x;"
,"}"])
(const [])
templatePointerWidth = defineTemplate
(SymPath ["Pointer"] "width")
(FuncTy [PointerTy (VarTy "p")] LongTy)
"gets the byte size of a pointer."
(toTemplate "long $NAME ($p *p)")
(toTemplate $ unlines ["$DECL {"
," return sizeof(*p);"
,"}"])
(const [])
templatePointerToLong = defineTemplate
(SymPath ["Pointer"] "to-long")
(FuncTy [PointerTy (VarTy "p")] LongTy)
"converts a pointer to a long integer."
(toTemplate "long $NAME ($p *p)")
(toTemplate $ unlines ["$DECL {"
," return (long)p;"
,"}"])
(const [])
templatePointerFromLong = defineTemplate
(SymPath ["Pointer"] "from-long")
(FuncTy [LongTy] (PointerTy (VarTy "p")))
"converts a long integer to a pointer."
(toTemplate "$p* $NAME (long p)")
(toTemplate $ unlines ["$DECL {"
," return ($p*)p;"
,"}"])
(const [])
-- | The System module contains functions for various OS related things like timing and process control.
systemModule :: Env
systemModule = Env { envBindings = bindings
@ -97,6 +155,7 @@ systemModule = Env { envBindings = bindings
, envFunctionNestingLevel = 0 }
where bindings = Map.fromList [ templateExit ]
-- | A template function for exiting.
templateExit :: (String, Binder)
templateExit = defineTemplate

38
test/pointer.carp Normal file
View File

@ -0,0 +1,38 @@
(load "Test.carp")
(use-all Test Pointer)
; we go to the middle of a chunk of 10 safe elements
(def x (add (Array.raw (the (Array Int) (Array.allocate 10))) 5l))
(def xa (to-long x))
(def w (width x))
; these tests are sadly a little unsafe
(deftest test
(assert-equal test
1l
; we assume that the width of a char is 1
(width (Array.raw (the (Array Char) [])))
"Pointer.width works as expected"
)
(assert-equal test
(+ xa (* 3l w))
(to-long (add x 3l))
"Pointer.add works as expected"
)
(assert-equal test
(- xa (* 3l w))
(to-long (sub x 3l))
"Pointer.sub works as expected"
)
(assert-equal test
(+ xa w)
(to-long (inc x))
"Pointer.inc works as expected"
)
(assert-equal test
(- xa w)
(to-long (dec x))
"Pointer.dec works as expected"
)
)