Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Chris Müller
cherry
Commits
63f7a1ed
Commit
63f7a1ed
authored
Jul 19, 2013
by
Chris Müller
Browse files
Move sources into its own bootstrap build
parent
dee7ec4a
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
63f7a1ed
...
...
@@ -12,6 +12,7 @@ set(CHERRY_VERSION 0.1)
include_directories
(
crystal/include
)
include_directories
(
include
)
add_subdirectory
(
source
)
add_subdirectory
(
test
)
#add_subdirectory(source)
add_subdirectory
(
bootstrap
)
#add_subdirectory(test)
bootstrap/CMakeLists.txt
0 → 100644
View file @
63f7a1ed
set
(
BOOTSTRAP_SOURCES
bootstrap.c
array.c
read.c
eval.c
value.c
unicode.c
tables.c
runtime.c
primitives.c
)
add_executable
(
bootstrap-cherry
${
BOOTSTRAP_SOURCES
}
)
target_link_libraries
(
bootstrap-cherry readline gc
)
source
/array.c
→
bootstrap
/array.c
View file @
63f7a1ed
...
...
@@ -16,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "
cherry/array
.h"
#include "
bootstrap
.h"
#include <assert.h>
#include <string.h>
#include <gc.h>
struct
org_
cherry_array
struct
cherry_array
{
uint8_t
*
data
;
size_t
alloc
;
...
...
@@ -31,12 +31,12 @@ struct org_cherry_array
struct
org_
cherry_array
*
org_
cherry_array_new
(
size_t
init_capacity
)
struct
cherry_array
*
cherry_array_new
(
size_t
init_capacity
)
{
assert
(
init_capacity
!=
0
);
struct
org_
cherry_array
*
array
=
GC_MALLOC
(
sizeof
(
struct
org_
cherry_array
));
struct
cherry_array
*
array
=
GC_MALLOC
(
sizeof
(
struct
cherry_array
));
array
->
alloc
=
init_capacity
;
array
->
length
=
0
;
array
->
data
=
GC_MALLOC
(
sizeof
(
uint8_t
)
*
array
->
alloc
);
...
...
@@ -47,7 +47,7 @@ org_cherry_array_new(size_t init_capacity)
size_t
org_
cherry_array_size
(
struct
org_
cherry_array
*
array
)
cherry_array_size
(
struct
cherry_array
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -57,7 +57,7 @@ org_cherry_array_size(struct org_cherry_array* array)
size_t
org_
cherry_array_capacity
(
struct
org_
cherry_array
*
array
)
cherry_array_capacity
(
struct
cherry_array
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -66,7 +66,7 @@ org_cherry_array_capacity(struct org_cherry_array* array)
size_t
org_
cherry_array_ensure
(
struct
org_
cherry_array
*
array
,
size_t
min_capacity
)
cherry_array_ensure
(
struct
cherry_array
*
array
,
size_t
min_capacity
)
{
assert
(
array
!=
0
);
...
...
@@ -81,7 +81,7 @@ org_cherry_array_ensure(struct org_cherry_array* array, size_t min_capacity)
size_t
org_
cherry_array_trim
(
struct
org_
cherry_array
*
array
)
cherry_array_trim
(
struct
cherry_array
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -93,11 +93,11 @@ org_cherry_array_trim(struct org_cherry_array* array)
void
org_
cherry_array_append
(
struct
org_
cherry_array
*
array
,
cy_
const_pointer_t
data
,
size_t
size
)
cherry_array_append
(
struct
cherry_array
*
array
,
const_pointer_t
data
,
size_t
size
)
{
assert
(
array
!=
0
);
org_
cherry_array_ensure
(
array
,
array
->
length
+
size
);
cherry_array_ensure
(
array
,
array
->
length
+
size
);
memcpy
(
array
->
data
+
array
->
length
,
data
,
size
);
...
...
@@ -106,14 +106,14 @@ org_cherry_array_append(struct org_cherry_array* array, cy_const_pointer_t data,
int
org_
cherry_array_insert
(
struct
org_
cherry_array
*
array
,
size_t
index
,
cy_
const_pointer_t
data
,
size_t
size
)
cherry_array_insert
(
struct
cherry_array
*
array
,
size_t
index
,
const_pointer_t
data
,
size_t
size
)
{
assert
(
array
!=
0
);
if
(
index
>=
array
->
length
)
return
FALSE
;
org_
cherry_array_ensure
(
array
,
array
->
length
+
size
);
cherry_array_ensure
(
array
,
array
->
length
+
size
);
memmove
(
array
->
data
+
index
+
size
,
array
->
data
+
index
,
array
->
length
-
index
);
memcpy
(
array
->
data
+
index
,
data
,
size
);
...
...
@@ -125,20 +125,20 @@ org_cherry_array_insert(struct org_cherry_array* array, size_t index, cy_const_p
int
org_
cherry_array_replace
(
struct
org_
cherry_array
*
array
,
size_t
index
,
cy_
const_pointer_t
data
,
size_t
size
)
cherry_array_replace
(
struct
cherry_array
*
array
,
size_t
index
,
const_pointer_t
data
,
size_t
size
)
{
assert
(
array
!=
0
);
if
(
index
>=
array
->
length
&&
index
+
size
>
array
->
length
)
return
FALSE
;
org_
cherry_array_ensure
(
array
,
array
->
length
+
size
);
cherry_array_ensure
(
array
,
array
->
length
+
size
);
memcpy
(
array
->
data
+
index
,
data
,
size
);
}
int
org_
cherry_array_remove
(
struct
org_
cherry_array
*
array
,
size_t
index
,
size_t
size
)
cherry_array_remove
(
struct
cherry_array
*
array
,
size_t
index
,
size_t
size
)
{
assert
(
array
!=
0
);
...
...
@@ -155,7 +155,7 @@ org_cherry_array_remove(struct org_cherry_array* array, size_t index, size_t siz
void
org_
cherry_array_clear
(
struct
org_
cherry_array
*
array
)
cherry_array_clear
(
struct
cherry_array
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -164,8 +164,8 @@ org_cherry_array_clear(struct org_cherry_array* array)
cy_
pointer_t
org_
cherry_array_get
(
struct
org_
cherry_array
*
array
,
size_t
index
)
pointer_t
cherry_array_get
(
struct
cherry_array
*
array
,
size_t
index
)
{
assert
(
array
!=
0
);
...
...
@@ -176,8 +176,8 @@ org_cherry_array_get(struct org_cherry_array* array, size_t index)
}
cy_
pointer_t
org_
cherry_array_clone
(
struct
org_
cherry_array
*
array
)
pointer_t
cherry_array_clone
(
struct
cherry_array
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -192,23 +192,23 @@ org_cherry_array_clone(struct org_cherry_array* array)
}
struct
org_
cherry_ptrarray
struct
cherry_ptrarray
{
cy_
pointer_t
*
data
;
pointer_t
*
data
;
size_t
alloc
;
size_t
length
;
};
struct
org_
cherry_ptrarray
*
org_
cherry_ptrarray_new
(
size_t
init_capacity
)
struct
cherry_ptrarray
*
cherry_ptrarray_new
(
size_t
init_capacity
)
{
assert
(
init_capacity
!=
0
);
struct
org_
cherry_ptrarray
*
array
=
GC_MALLOC
(
sizeof
(
struct
org_
cherry_ptrarray
));
struct
cherry_ptrarray
*
array
=
GC_MALLOC
(
sizeof
(
struct
cherry_ptrarray
));
array
->
alloc
=
init_capacity
;
array
->
length
=
0
;
array
->
data
=
GC_MALLOC
(
sizeof
(
cy_
pointer_t
)
*
array
->
alloc
);
array
->
data
=
GC_MALLOC
(
sizeof
(
pointer_t
)
*
array
->
alloc
);
return
array
;
}
...
...
@@ -216,7 +216,7 @@ org_cherry_ptrarray_new(size_t init_capacity)
size_t
org_
cherry_ptrarray_size
(
struct
org_
cherry_ptrarray
*
array
)
cherry_ptrarray_size
(
struct
cherry_ptrarray
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -225,7 +225,7 @@ org_cherry_ptrarray_size(struct org_cherry_ptrarray* array)
size_t
org_
cherry_ptrarray_capacity
(
struct
org_
cherry_ptrarray
*
array
)
cherry_ptrarray_capacity
(
struct
cherry_ptrarray
*
array
)
{
assert
(
array
!=
0
);
...
...
@@ -234,14 +234,14 @@ org_cherry_ptrarray_capacity(struct org_cherry_ptrarray* array)
size_t
org_
cherry_ptrarray_ensure
(
struct
org_
cherry_ptrarray
*
array
,
size_t
min_capacity
)
cherry_ptrarray_ensure
(
struct
cherry_ptrarray
*
array
,
size_t
min_capacity
)
{
assert
(
array
!=
0
);
if
(
array
->
alloc
<
min_capacity
)
{
size_t
new_capacity
=
(
array
->
alloc
>>
1
);
array
->
alloc
=
(
new_capacity
>
min_capacity
)
?
new_capacity
:
min_capacity
;
array
->
data
=
GC_REALLOC
(
array
->
data
,
sizeof
(
cy_
pointer_t
)
*
array
->
alloc
);
array
->
data
=
GC_REALLOC
(
array
->
data
,
sizeof
(
pointer_t
)
*
array
->
alloc
);
}
return
array
->
alloc
;
...
...
@@ -249,11 +249,11 @@ org_cherry_ptrarray_ensure(struct org_cherry_ptrarray* array, size_t min_capacit
size_t
org_
cherry_ptrarray_trim
(
struct
org_
cherry_ptrarray
*
array
)
cherry_ptrarray_trim
(
struct
cherry_ptrarray
*
array
)
{
assert
(
array
!=
0
);
array
->
data
=
GC_REALLOC
(
array
->
data
,
sizeof
(
cy_
pointer_t
)
*
array
->
length
);
array
->
data
=
GC_REALLOC
(
array
->
data
,
sizeof
(
pointer_t
)
*
array
->
length
);
array
->
alloc
=
array
->
length
;
return
array
->
alloc
;
...
...
@@ -261,11 +261,11 @@ org_cherry_ptrarray_trim(struct org_cherry_ptrarray* array)
void
org_
cherry_ptrarray_append
(
struct
org_
cherry_ptrarray
*
array
,
cy_
pointer_t
ptr
)
cherry_ptrarray_append
(
struct
cherry_ptrarray
*
array
,
pointer_t
ptr
)
{
assert
(
array
!=
0
);
org_
cherry_ptrarray_ensure
(
array
,
array
->
length
+
1
);
cherry_ptrarray_ensure
(
array
,
array
->
length
+
1
);
*
(
array
->
data
+
array
->
length
)
=
ptr
;
...
...
@@ -274,16 +274,16 @@ org_cherry_ptrarray_append(struct org_cherry_ptrarray* array, cy_pointer_t ptr)
int
org_
cherry_ptrarray_insert
(
struct
org_
cherry_ptrarray
*
array
,
size_t
index
,
cy_
pointer_t
ptr
)
cherry_ptrarray_insert
(
struct
cherry_ptrarray
*
array
,
size_t
index
,
pointer_t
ptr
)
{
assert
(
array
!=
0
);
if
(
index
>=
array
->
length
)
return
FALSE
;
org_
cherry_ptrarray_ensure
(
array
,
array
->
length
+
1
);
cherry_ptrarray_ensure
(
array
,
array
->
length
+
1
);
memmove
(
array
->
data
+
index
+
1
,
array
->
data
+
index
,
(
array
->
length
-
index
)
*
sizeof
(
cy_
pointer_t
));
memmove
(
array
->
data
+
index
+
1
,
array
->
data
+
index
,
(
array
->
length
-
index
)
*
sizeof
(
pointer_t
));
*
(
array
->
data
+
index
)
=
ptr
;
...
...
@@ -293,32 +293,32 @@ org_cherry_ptrarray_insert(struct org_cherry_ptrarray* array, size_t index, cy_p
}
cy_
pointer_t
org_
cherry_ptrarray_replace
(
struct
org_
cherry_ptrarray
*
array
,
size_t
index
,
cy_
pointer_t
ptr
)
pointer_t
cherry_ptrarray_replace
(
struct
cherry_ptrarray
*
array
,
size_t
index
,
pointer_t
ptr
)
{
assert
(
array
!=
0
);
if
(
index
>=
array
->
length
)
return
0
;
cy_
pointer_t
data
=
*
(
array
->
data
+
index
);
pointer_t
data
=
*
(
array
->
data
+
index
);
*
(
array
->
data
+
index
)
=
ptr
;
return
data
;
}
cy_
pointer_t
org_
cherry_ptrarray_remove
(
struct
org_
cherry_ptrarray
*
array
,
size_t
index
)
pointer_t
cherry_ptrarray_remove
(
struct
cherry_ptrarray
*
array
,
size_t
index
)
{
assert
(
array
!=
0
);
if
(
index
>=
array
->
length
)
return
FALSE
;
cy_
pointer_t
data
=
*
(
array
->
data
+
index
);
pointer_t
data
=
*
(
array
->
data
+
index
);
memmove
(
array
->
data
+
index
,
array
->
data
+
index
+
1
,
(
array
->
length
-
index
-
1
)
*
sizeof
(
cy_
pointer_t
));
memmove
(
array
->
data
+
index
,
array
->
data
+
index
+
1
,
(
array
->
length
-
index
-
1
)
*
sizeof
(
pointer_t
));
array
->
length
-=
1
;
...
...
@@ -326,8 +326,8 @@ org_cherry_ptrarray_remove(struct org_cherry_ptrarray* array, size_t index)
}
cy_
pointer_t
org_
cherry_ptrarray_get
(
struct
org_
cherry_ptrarray
*
array
,
size_t
index
)
pointer_t
cherry_ptrarray_get
(
struct
cherry_ptrarray
*
array
,
size_t
index
)
{
assert
(
array
!=
0
);
...
...
@@ -338,7 +338,7 @@ org_cherry_ptrarray_get(struct org_cherry_ptrarray* array, size_t index)
}
void
org_
cherry_ptrarray_clear
(
struct
org_
cherry_ptrarray
*
array
)
cherry_ptrarray_clear
(
struct
cherry_ptrarray
*
array
)
{
assert
(
array
!=
0
);
array
->
length
=
0
;
...
...
source/cherry
.c
→
bootstrap/bootstrap
.c
View file @
63f7a1ed
#include <stdio.h>
#include <stdlib.h>
/*
* Cherry programming language
* Copyright (C) 2013 Christoph Mueller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bootstrap.h"
#include <getopt.h>
#include <readline/readline.h>
#include <gc.h>
#include "cherry/array.h"
#include "cherry/read.h"
static
void
print_usage
(
FILE
*
out
,
const
char
*
prog
)
{
...
...
@@ -16,7 +32,7 @@ print_usage(FILE* out, const char* prog) {
}
static
const
cy_
byte_t
*
static
const
byte_t
*
get_text
(
const
char
*
filename
,
const
char
*
mode
)
{
FILE
*
file
=
fopen
(
filename
,
mode
);
size_t
filesize
;
...
...
@@ -28,8 +44,8 @@ get_text(const char* filename, const char* mode) {
filesize
=
ftell
(
file
);
rewind
(
file
);
cy_
byte_t
*
data
=
GC_MALLOC
(
filesize
*
sizeof
(
cy_
byte_t
));
fread
(
data
,
sizeof
(
cy_
byte_t
),
filesize
,
file
);
byte_t
*
data
=
GC_MALLOC
(
filesize
*
sizeof
(
byte_t
));
fread
(
data
,
sizeof
(
byte_t
),
filesize
,
file
);
fclose
(
file
);
return
data
;
...
...
@@ -37,77 +53,77 @@ get_text(const char* filename, const char* mode) {
static
void
org_
cherry_process_file
(
const
char
*
filename
,
const
cy_
byte_t
*
method
,
struct
org_
cherry_value
*
arguments
)
cherry_process_file
(
const
char
*
filename
,
const
byte_t
*
method
,
struct
cherry_value
*
arguments
)
{
const
cy_
byte_t
*
src
=
get_text
(
filename
,
"rb"
);
const
byte_t
*
src
=
get_text
(
filename
,
"rb"
);
if
(
src
==
0
)
{
fprintf
(
stderr
,
"cherry: couldn't load %s
\n
"
,
filename
);
exit
(
EXIT_FAILURE
);
}
struct
org_
cherry_environment
*
env
=
org_
cherry_environment
();
struct
org_
cherry_context
*
context
=
org_
cherry_context
(
src
,
filename
,
CY_
SUPRESS_COMMENTS
);
struct
cherry_environment
*
env
=
cherry_environment
();
struct
cherry_context
*
context
=
cherry_context
(
src
,
filename
,
SUPRESS_COMMENTS
);
struct
org_
cherry_value
*
exp
=
org_
cherry_read
(
context
);
struct
cherry_value
*
exp
=
cherry_read
(
context
);
org_
cherry_env_push_exception_point
(
env
);
cherry_env_push_exception_point
(
env
);
if
(
!
setjmp
(
EXCEPTION_JUMP
(
env
)))
{
while
(
exp
!=
0
)
{
org_
cherry_eval
(
env
,
exp
);
exp
=
org_
cherry_read
(
context
);
cherry_eval
(
env
,
exp
);
exp
=
cherry_read
(
context
);
}
if
(
method
)
{
struct
org_
cherry_value
*
main
=
org_
cherry_list_cons
(
org_
cherry_symbol
(
method
),
arguments
);
struct
cherry_value
*
main
=
cherry_list_cons
(
cherry_symbol
(
method
),
arguments
);
org_
cherry_eval
(
env
,
main
);
cherry_eval
(
env
,
main
);
}
}
else
{
fprintf
(
stderr
,
"EXCEPTION: "
);
org_
cherry_print
(
stderr
,
HEAD
(
EXCEPTION_DATA
(
env
)));
cherry_print
(
stderr
,
HEAD
(
EXCEPTION_DATA
(
env
)));
fprintf
(
stderr
,
"
\n
"
);
exit
(
EXIT_FAILURE
);
}
org_
cherry_env_pop_exception_point
(
env
);
cherry_env_pop_exception_point
(
env
);
exit
(
EXIT_SUCCESS
);
}
static
void
org_
cherry_start_repl
(
void
)
cherry_start_repl
(
void
)
{
printf
(
"
Cherry Interpreter 0.1
\n\n
"
);
printf
(
"
Welcome to bootstrap-cherry
\n\n
"
);
struct
org_
cherry_environment
*
env
=
org_
cherry_environment
();
struct
cherry_environment
*
env
=
cherry_environment
();
org_
cherry_env_push_exception_point
(
env
);
cherry_env_push_exception_point
(
env
);
cy_
byte_t
*
line
=
(
cy_
byte_t
*
)
readline
(
"> "
);
struct
org_
cherry_context
*
context
=
org_
cherry_context_repl
(
line
);
byte_t
*
line
=
(
byte_t
*
)
readline
(
"> "
);
struct
cherry_context
*
context
=
cherry_context_repl
(
line
);
while
(
1
)
{
struct
org_
cherry_value
*
exp
=
org_
cherry_read
(
context
);
struct
cherry_value
*
exp
=
cherry_read
(
context
);
if
(
!
setjmp
(
EXCEPTION_JUMP
(
env
)))
{
org_
cherry_print
(
stdout
,
org_
cherry_eval
(
env
,
exp
));
cherry_print
(
stdout
,
cherry_eval
(
env
,
exp
));
printf
(
"
\n
"
);
}
else
{
fprintf
(
stderr
,
"EXCEPTION: "
);
org_
cherry_print
(
stderr
,
EXCEPTION_DATA
(
env
));
cherry_print
(
stderr
,
EXCEPTION_DATA
(
env
));
fprintf
(
stderr
,
"
\n
"
);
}
free
(
line
);
line
=
(
cy_
byte_t
*
)
readline
(
"> "
);
org_
cherry_context_repl_set_source
(
context
,
line
);
line
=
(
byte_t
*
)
readline
(
"> "
);
cherry_context_repl_set_source
(
context
,
line
);
}
org_
cherry_env_pop_exception_point
(
env
);
cherry_env_pop_exception_point
(
env
);
}
...
...
@@ -120,13 +136,13 @@ main(int argc, char** argv)
{
"main"
,
optional_argument
,
0
,
'M'
}
};
org_
cherry_initialize
(
0
);
cherry_initialize
(
0
);
int
ch
;
const
char
*
filename
=
0
;
const
cy_
byte_t
*
method
=
0
;
struct
org_
cherry_ptrarray
*
load_path
=
org_
cherry_ptrarray_new
(
4
);
struct
org_
cherry_value
*
arguments
=
org_
cherry_emptylist
;
const
byte_t
*
method
=
0
;
struct
cherry_ptrarray
*
load_path
=
cherry_ptrarray_new
(
4
);
struct
cherry_value
*
arguments
=
cherry_emptylist
;
while
(
(
ch
=
getopt_long
(
argc
,
argv
,
"hI:M:"
,
options
,
0
))
!=
-
1
)
{
switch
(
ch
)
{
...
...
@@ -134,7 +150,7 @@ main(int argc, char** argv)
print_usage
(
stdout
,
argv
[
0
]);
exit
(
EXIT_SUCCESS
);
case
'I'
:
org_
cherry_ptrarray_append
(
load_path
,
optarg
);
cherry_ptrarray_append
(
load_path
,
optarg
);
break
;
case
'M'
:
method
=
optarg
;
...
...
@@ -152,14 +168,14 @@ main(int argc, char** argv)
filename
=
argv
[
optind
++
];
while
(
optind
<
argc
)
{
arguments
=
org_
cherry_list_cons
(
org_
cherry_string
(
argv
[
optind
++
]),
arguments
);
arguments
=
cherry_list_cons
(
cherry_string
(
argv
[
optind
++
]),
arguments
);
}
if
(
filename
)
org_
cherry_process_file
(
filename
,
method
,
org_
cherry_list_reverse
(
arguments
));
cherry_process_file
(
filename
,
method
,
cherry_list_reverse
(
arguments
));
else
org_
cherry_start_repl
();
cherry_start_repl
();
return
EXIT_SUCCESS
;
return
EXIT_SUCCESS
;
}
bootstrap/bootstrap.h
0 → 100644
View file @
63f7a1ed
/*
* Cherry programming language
* Copyright (C) 2013 Christoph Mueller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
struct
cherry_environment
;
struct
cherry_value
;
#define TRUE 1
#define FALSE 0
typedef
void
*
pointer_t
;
typedef
const
void
*
const_pointer_t
;
typedef
uint8_t
byte_t
;
typedef
int64_t
fixnum_t
;
typedef
double
float_t
;
typedef
char
boolean_t
;
typedef
uint32_t
unicode_t
;
typedef
uint32_t
flags_t
;
typedef
struct
cherry_value
*
(
*
primitive_t
)(
struct
cherry_environment
*
env
,
struct
cherry_value
*
args
);
enum
cherry_value_type
{
EMPTYLIST
,
BOOLEAN
,
DOT
,
FIXNUM
,
FLOAT
,
STRING
,
CHAR
,
PAIR
,
TUPLE
,
SYMBOL
,
PRIMITIVE
,
PROCEDURE
};
struct
cherry_value
{
enum
cherry_value_type
tag
;
union
{
// trivial
boolean_t
boolean_value
;
fixnum_t
fixnum_value
;
float_t
float_value
;
unicode_t
char_value
;
primitive_t
fun_value
;
const
byte_t
*
string_value
;
const
byte_t
*
symbol_value
;
// lists
struct
{
struct
cherry_value
*
head
;
struct
cherry_value
*
tail
;
}
pair
;
// tuples
struct
{
struct
cherry_value
**
data
;
size_t
size
;
}
tuple
;
// procedures
struct
{
struct
cherry_value
*
param
;
struct
cherry_value
*
body
;
struct
cherry_environment
*
env
;
}
proc
;
};
};
#define TYPE(value) (value->tag)
#define IS_NULL(value) (value->tag == EMPTYLIST)
#define IS_BOOLEAN(value) (value->tag == BOOLEAN)
#define IS_DOT(value) (value->tag == DOT)
#define IS_FIXNUM(value) (value->tag == FIXNUM)
#define IS_STRING(value) (value->tag == STRING)
#define IS_SYMBOL(value) (value->tag == SYMBOL)
#define IS_FLOAT(value) (value->tag == FLOAT)
#define IS_CHAR(value) (value->tag == CHAR)
#define IS_PAIR(value) (value->tag == PAIR)
#define IS_PRIMITIVE(value) (value->tag == PRIMITIVE)