runtime.h 6.48 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * 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

21
#include "cherry/standard.h"
22
#include <stdio.h>
23
#include <string.h>
24
25

enum org_cherry_value_type {
26
    CY_EMPTYLIST,
27
28
29
30
31
	CY_BOOLEAN,
	CY_FIXNUM,
	CY_FLOAT,
	CY_STRING, 
	CY_CHAR,
32
    CY_PAIR,
33
34
35
    CY_SYMBOL,
	CY_PRIMITIVE,
	CY_PROCEDURE
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
};


struct org_cherry_meta {
  enum org_cherry_value_type type;
};


struct org_cherry_value {
    struct org_cherry_meta meta;

	union {
		cy_boolean_t boolean_value;

		cy_fixnum_t fixnum_value;

		cy_float_t float_value;

54
		const cy_byte_t* string_value;
55
		cy_unicode_t char_value;
56

57
		const cy_byte_t* symbol_value;
58
59

		struct org_cherry_value* (*fun_value)(struct org_cherry_value*); 
60
61
62
	};
};

63
#define TO_VALUE(value) ((struct org_cherry_value*) value)
64
#define IS_NULL(value) (value->meta.type == CY_EMPTYLIST)
65
66
67
68
69
70
71
#define IS_BOOLEAN(value) (value->meta.type == CY_BOOLEAN)
#define IS_FIXNUM(value) (value->meta.type == CY_FIXNUM)
#define IS_STRING(value) (value->meta.type == CY_STRING)
#define IS_SYMBOL(value) (value->meta.type == CY_SYMBOL)
#define IS_FLOAT(value) (value->meta.type == CY_FLOAT)
#define IS_CHAR(value) (value->meta.type == CY_CHAR)
#define IS_PAIR(value) (value->meta.type == CY_PAIR)
72
73
#define IS_PRIMITIVE(value) (value->meta.type == CY_PRIMITIVE)
#define IS_PROCEDURE(value) (value->meta.type == CY_PROCEDURE)
74

75
76
77
78
79
80
81
82
83
84
#define org_cherry_string_size(STR) (strlen(STR) + 1)

const cy_byte_t*            org_cherry_string_dup(const cy_byte_t* str);

struct org_cherry_value*	org_cherry_fixnum_from_string(const cy_byte_t* str, int base);
struct org_cherry_value*	org_cherry_float_from_string(const cy_byte_t* str);
struct org_cherry_value*	org_cherry_char_from_string(const cy_byte_t* str);
struct org_cherry_value*	org_cherry_symbol_from_string(const cy_byte_t* str);
struct org_cherry_value*	org_cherry_string_from_string(const cy_byte_t* str);

85
struct org_cherry_value*    org_cherry_value_alloc(void);
86
struct org_cherry_value*    org_cherry_symbol(const cy_byte_t* symbol_value);
87
88
struct org_cherry_value* 	org_cherry_fixnum(cy_fixnum_t value);
struct org_cherry_value* 	org_cherry_float(cy_float_t float_value);
89
struct org_cherry_value* 	org_cherry_string(const cy_byte_t* string_value);
90
91
struct org_cherry_value* 	org_cherry_char(cy_unicode_t char_value);

92
93
94
95
96
97
98
struct org_cherry_pair {
  struct org_cherry_meta meta;

  struct org_cherry_value* head;
  struct org_cherry_value* tail;
};

99
100
101
102
103
#define TO_PAIR(obj) ((struct org_cherry_pair*) obj)
#define HEAD(pair) ((struct org_cherry_pair*) pair)->head
#define TAIL(pair) ((struct org_cherry_pair*) pair)->tail

struct org_cherry_value*     org_cherry_list_cons(struct org_cherry_value* head, struct org_cherry_value* tail);
104

105
106
107
108
109
110
111
112
113
114
115
116
117
struct org_cherry_procedure {
	struct org_cherry_meta meta;

	struct org_cherry_value* param;
	struct org_cherry_value* body;
	struct org_cherry_symbollist* env;
};

#define TO_PROC(obj) ((struct org_cherry_procedure*) obj)

struct org_cherry_value*	org_cherry_procedure(struct org_cherry_symbollist* env,
												 struct org_cherry_value* param,
												 struct org_cherry_value* body);
118
119
120
121
122

// ----------------------------------------------------------------------------
// Symboltables
// ----------------------------------------------------------------------------

123
struct org_cherry_symbollist;
124

125
struct org_cherry_symbollist*	org_cherry_symbollist(void);
126
struct org_cherry_value*		org_cherry_symbollist_get(struct org_cherry_symbollist* table, const cy_byte_t* name);
127

128
129
130
131
132
struct org_cherry_symbollist*   org_cherry_env_push(struct org_cherry_symbollist* env);
struct org_cherry_symbollist*   org_cherry_env_pop(struct org_cherry_symbollist* env);
struct org_cherry_value*        org_cherry_env_lookup(struct org_cherry_symbollist* env, struct org_cherry_value* symbol);
int                             org_cherry_env_add(struct org_cherry_symbollist* env, struct org_cherry_value* symbol, struct org_cherry_value* value);

133
extern struct org_cherry_symbollist*    org_cherry_global_symbollist;
134

135
extern struct org_cherry_value*         org_cherry_emptylist;
136
137
extern struct org_cherry_value*         org_cherry_true;
extern struct org_cherry_value*         org_cherry_false;
138
extern struct org_cherry_value*         org_cherry_symbol_quote;
139
140
141
extern struct org_cherry_value*         org_cherry_symbol_define;
extern struct org_cherry_value*         org_cherry_symbol_lambda;
extern struct org_cherry_value*         org_cherry_symbol_if;
142

143

144

145
146
147
// ----------------------------------------------------------------------------
// Evaluation
// ----------------------------------------------------------------------------
148

149
150
151
152
#define IS_FALSE(obj) (IS_BOOLEAN(obj) && !obj->boolean_value)

#define IS_TRUE(obj) (!IS_FALSE(obj))

153
#define IS_SELF_EVALUATING(value) \
154
  (IS_BOOLEAN(value) || IS_FIXNUM(value) || IS_CHAR(value) || IS_STRING(value) || IS_FLOAT(value))
155

156
157
#define IS_VARIABLE(value) \
  IS_SYMBOL(value)
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#define IS_TAGGED(value, symbol) \
  (IS_PAIR(value) && IS_SYMBOL(HEAD(value)) && HEAD(value) == symbol)

#define IS_QUOTE(value) \
  IS_TAGGED(value, org_cherry_symbol_quote)

#define IS_DEFINE(value) \
  IS_TAGGED(value, org_cherry_symbol_define)

#define IS_IF(value) \
  IS_TAGGED(value, org_cherry_symbol_if)

#define IS_LAMBDA(value) \
  IS_TAGGED(value, org_cherry_symbol_lambda)

#define IS_APPLICATION(value) \
  IS_PAIR(value)

177
178
179
#define TEXT_OF_QUOTATION(value) \
	HEAD(TAIL(value))

180
181
182
183
struct org_cherry_value*    org_cherry_eval(struct org_cherry_symbollist* env, struct org_cherry_value* exp);



184
185
186
187
188
189
190
// ----------------------------------------------------------------------------
// Print
// ----------------------------------------------------------------------------

void org_cherry_print(FILE* out, struct org_cherry_value* value);


191
192
193
// ----------------------------------------------------------------------------
// Default
// ----------------------------------------------------------------------------
194

195
void org_cherry_initialize(struct org_cherry_pair* arguments);
196