core: add a byte type

This commit is contained in:
hellerve 2019-10-24 11:23:38 +02:00
parent 16e9418d25
commit f1f252639f
36 changed files with 990 additions and 0 deletions

61
core/Byte.carp Normal file
View File

@ -0,0 +1,61 @@
(system-include "carp_byte.h")
(defmodule Byte
(register + (λ [Byte Byte] Byte))
(register - (λ [Byte Byte] Byte))
(register * (λ [Byte Byte] Byte))
(register / (λ [Byte Byte] Byte))
(register < (λ [Byte Byte] Bool))
(register > (λ [Byte Byte] Bool))
(register = (λ [Byte Byte] Bool))
(register mod (λ [Byte Byte] Byte))
(register bit-shift-left (λ [Byte Byte] Byte))
(register bit-shift-right (λ [Byte Byte] Byte))
(register bit-and (λ [Byte Byte] Byte))
(register bit-or (λ [Byte Byte] Byte))
(register bit-xor (λ [Byte Byte] Byte))
(register bit-not (λ [Byte] Byte))
(register inc (λ [Byte] Byte))
(register dec (λ [Byte] Byte))
(register copy (λ [&Byte] Byte))
(register to-int (λ [Byte] Int))
(register from-int (λ [Int] Byte))
(defn even? [a] (= (mod a 2b) 0b))
(defn odd? [a] (not (even? a)))
(defn zero [] 0b)
(defn add-ref [x y]
(Byte.+ @x @y))
;; Move to generic math module?
(defn clamp [min, max, val]
(if (> val max)
max
(if (< val min)
min
val)))
(doc pow "Raise x to the power of y.")
(defn pow [x y]
(let-do [r 1b]
(while (/= y 0b)
(do
(when (/= (bit-and y 1b) 0b)
(set! r (* r x)))
(set! y (/ y 2b))
(set! x (* x x))))
r))
)
(defmodule ByteRef
(defn = [a b]
(Byte.= @a @b))
(defn < [a b]
(Byte.< @a @b))
(defn > [a b]
(Byte.> @a @b))
)

View File

@ -23,6 +23,7 @@
(load "Result.carp")
(load "Dynamic.carp")
(load "Format.carp")
(load "Byte.carp")
(load "Int.carp")
(load "Long.carp")
(load "Double.carp")

View File

@ -179,6 +179,12 @@
(register from-string (λ [&String] Int))
)
(defmodule Byte
(register str (Fn [Byte] String))
(register format (Fn [&String Byte] String))
(register from-string (λ [&String] Byte))
)
(defmodule Float
(register str (Fn [Float] String))
(register format (Fn [&String Float] String))

36
core/carp_byte.h Normal file
View File

@ -0,0 +1,36 @@
typedef uint8_t byte;
uint8_t Byte__PLUS_(uint8_t x, uint8_t y) { return x + y; }
uint8_t Byte__MINUS_(uint8_t x, uint8_t y) { return x - y; }
uint8_t Byte__MUL_(uint8_t x, uint8_t y) { return x * y; }
uint8_t Byte__DIV_(uint8_t x, uint8_t y) { return x / y; }
bool Byte__EQ_(uint8_t x, uint8_t y) { return x == y; }
bool Byte__LT_(uint8_t x, uint8_t y) { return x < y; }
bool Byte__GT_(uint8_t x, uint8_t y) { return x > y; }
uint8_t Byte_inc(uint8_t x) { return x + 1; }
uint8_t Byte_dec(uint8_t x) { return x - 1; }
uint8_t Byte_bit_MINUS_shift_MINUS_left(uint8_t x, uint8_t y) { return x << y; }
uint8_t Byte_bit_MINUS_shift_MINUS_right(uint8_t x, uint8_t y) { return x >> y; }
uint8_t Byte_bit_MINUS_and(uint8_t x, uint8_t y) { return x & y; }
uint8_t Byte_bit_MINUS_or(uint8_t x, uint8_t y) { return x | y; }
uint8_t Byte_bit_MINUS_xor(uint8_t x, uint8_t y) { return x ^ y; }
uint8_t Byte_bit_MINUS_not(uint8_t x) { return ~x; }
uint8_t Byte_copy(const uint8_t *x) { return *x; }
uint8_t Byte_mod(uint8_t x, uint8_t divider) {
return x % divider;
}
bool Byte_mask(uint8_t a, uint8_t b) {
return a & b;
}
int Byte_to_MINUS_int(uint8_t a) {
return a;
}
uint8_t Byte_from_MINUS_int(int a) {
return a;
}

View File

@ -243,6 +243,24 @@ long Long_from_MINUS_string(const String *s) {
return atol(*s);
}
String Byte_str(uint8_t x) {
int size = snprintf(NULL, 0, "%ub", x)+1;
String buffer = CARP_MALLOC(size);
snprintf(buffer, size, "%ub", x);
return buffer;
}
String Byte_format(const String* str, uint8_t x) {
int size = snprintf(NULL, 0, *str, x)+1;
String buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, x);
return buffer;
}
uint8_t Byte_from_MINUS_string(const String *s) {
return atoi(*s);
}
int String_index_MINUS_of_MINUS_from(const String *s, char c, int i) {
/* Return index of first occurrence of `c` in `s` AFTER index i
* Returns -1 if not found

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

684
docs/core/Byte.html Normal file
View File

@ -0,0 +1,684 @@
<!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="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>
</ul>
</div>
</div>
<h1>
Byte
</h1>
<div class="module-description">
</div>
<div class="binder">
<a class="anchor" href="#*">
<h3 id="*">
*
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#+">
<h3 id="+">
+
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#-">
<h3 id="-">
-
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#/">
<h3 id="/">
/
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#&lt;">
<h3 id="&lt;">
&lt;
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Bool)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#=">
<h3 id="=">
=
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Bool)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#&gt;">
<h3 id="&gt;">
&gt;
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Bool)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#add-ref">
<h3 id="add-ref">
add-ref
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [&amp;Byte, &amp;Byte] Byte)
</p>
<pre class="args">
(add-ref x y)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-and">
<h3 id="bit-and">
bit-and
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-not">
<h3 id="bit-not">
bit-not
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-or">
<h3 id="bit-or">
bit-or
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-shift-left">
<h3 id="bit-shift-left">
bit-shift-left
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-shift-right">
<h3 id="bit-shift-right">
bit-shift-right
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#bit-xor">
<h3 id="bit-xor">
bit-xor
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#clamp">
<h3 id="clamp">
clamp
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [a, a, a] a)
</p>
<pre class="args">
(clamp min max val)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#copy">
<h3 id="copy">
copy
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [&amp;Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#dec">
<h3 id="dec">
dec
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#even?">
<h3 id="even?">
even?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [Byte] Bool)
</p>
<pre class="args">
(even? a)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#format">
<h3 id="format">
format
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [&amp;String, Byte] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#from-int">
<h3 id="from-int">
from-int
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Int] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#from-string">
<h3 id="from-string">
from-string
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [&amp;String] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#inc">
<h3 id="inc">
inc
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#mod">
<h3 id="mod">
mod
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#odd?">
<h3 id="odd?">
odd?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [Byte] Bool)
</p>
<pre class="args">
(odd? a)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#pow">
<h3 id="pow">
pow
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [Byte, Byte] Byte)
</p>
<pre class="args">
(pow x y)
</pre>
<p class="doc">
<p>Raise x to the power of y.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#str">
<h3 id="str">
str
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#to-int">
<h3 id="to-int">
to-int
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(λ [Byte] Int)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#zero">
<h3 id="zero">
zero
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [] Byte)
</p>
<pre class="args">
(zero)
</pre>
<p class="doc">
</p>
</div>
</div>
</body>
</html>

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -27,6 +27,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -23,6 +23,11 @@
Int
</a>
</li>
<li>
<a href="Byte.html">
Byte
</a>
</li>
<li>
<a href="Long.html">
Long

View File

@ -13,6 +13,7 @@
(save-docs Dynamic
Int
Byte
Long
Bool
Float

View File

@ -98,6 +98,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
Arr _ -> visitArray indent xobj
Num IntTy num -> return (show (round num :: Int))
Num LongTy num -> return (show (round num :: Int) ++ "l")
Num ByteTy num -> return (show (round num :: Int))
Num FloatTy num -> return (show num ++ "f")
Num DoubleTy num -> return (show num)
Num _ _ -> error "Can't emit invalid number type."

View File

@ -257,6 +257,7 @@ pretty = visit 0
Dict dict -> "{" ++ joinWithSpace (map (visit indent) (concatMap (\(a, b) -> [a, b]) (Map.toList dict))) ++ "}"
Num IntTy num -> show (round num :: Int)
Num LongTy num -> show num ++ "l"
Num ByteTy num -> show num
Num FloatTy num -> show num ++ "f"
Num DoubleTy num -> show num
Num _ _ -> error "Invalid number type."
@ -600,6 +601,7 @@ xobjToTy (XObj (Sym (SymPath _ "Int") _) _ _) = Just IntTy
xobjToTy (XObj (Sym (SymPath _ "Float") _) _ _) = Just FloatTy
xobjToTy (XObj (Sym (SymPath _ "Double") _) _ _) = Just DoubleTy
xobjToTy (XObj (Sym (SymPath _ "Long") _) _ _) = Just LongTy
xobjToTy (XObj (Sym (SymPath _ "Byte") _) _ _) = Just ByteTy
xobjToTy (XObj (Sym (SymPath _ "String") _) _ _) = Just StringTy
xobjToTy (XObj (Sym (SymPath _ "Pattern") _) _ _) = Just PatternTy
xobjToTy (XObj (Sym (SymPath _ "Char") _) _ _) = Just CharTy

View File

@ -58,6 +58,12 @@ integer :: Parsec.Parsec String ParseState XObj
integer = do (i, num) <- maybeSigned
return (XObj (Num IntTy (read num)) i Nothing)
byte :: Parsec.Parsec String ParseState XObj
byte = do (i, num) <- maybeSigned
_ <- Parsec.char 'b'
incColumn 1
return (XObj (Num ByteTy (read num)) i Nothing)
long :: Parsec.Parsec String ParseState XObj
long = do (i, num) <- maybeSigned
_ <- Parsec.char 'l'
@ -67,6 +73,7 @@ long = do (i, num) <- maybeSigned
number :: Parsec.Parsec String ParseState XObj
number = Parsec.try float <|>
Parsec.try floatNoPeriod <|>
Parsec.try byte <|>
Parsec.try double <|>
Parsec.try long <|>
Parsec.try integer

View File

@ -27,6 +27,7 @@ import Util
-- | Carp types.
data Ty = IntTy
| LongTy
| ByteTy
| BoolTy
| FloatTy
| DoubleTy
@ -60,6 +61,7 @@ instance Show Ty where
show FloatTy = "Float"
show DoubleTy = "Double"
show LongTy = "Long"
show ByteTy = "Byte"
show BoolTy = "Bool"
show StringTy = "String"
show PatternTy = "Pattern"
@ -107,6 +109,7 @@ tyToCManglePtr _ BoolTy = "bool"
tyToCManglePtr _ FloatTy = "float"
tyToCManglePtr _ DoubleTy = "double"
tyToCManglePtr _ LongTy = "long"
tyToCManglePtr _ ByteTy = "uint8_t"
tyToCManglePtr _ StringTy = "String"
tyToCManglePtr _ PatternTy = "Pattern"
tyToCManglePtr _ CharTy = "char"

50
test/byte_math.carp Normal file
View File

@ -0,0 +1,50 @@
(load "Test.carp")
(use-all Byte Test)
(deftest test
(assert-equal test
1b
(min 1b 2b)
"min works as expected")
(assert-equal test
2b
(max 1b 2b)
"max works as expected")
(assert-equal test
false
(even? 3b)
"even? works as expected")
(assert-equal test
true
(odd? 3b)
"odd? works as expected")
(assert-equal test
1b
(bit-and 3b 5b)
"bit-and works as expected")
(assert-equal test
5b
(bit-or 1b 4b)
"bit-or works as expected")
(assert-equal test
4b
(bit-xor 1b 5b)
"bit-xor works as expected")
(assert-equal test
1b
(bit-not 254b)
"bit-not works as expected")
(assert-equal test
8b
(bit-shift-left 2b 2b)
"bit-shift-left works as expected")
(assert-equal test
2b
(bit-shift-right 16b 3b)
"bit-shift-right works as expected")
(assert-equal test
1
(/ 3 2)
"integer division truncates as expected")
)