• R/O
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javaandroidc++linuxc#objective-ccocoa誰得qtrubybathyscaphegamephpguicwindows翻訳pythonomegattwitterframeworkbtronarduinovb.net計画中(planning stage)directxpreviewertestゲームエンジンdom

N88BASICが簡単に動くインタープリタを目指します。


コミットメタ情報

リビジョン31 (tree)
日時2018-10-19 07:48:09
作者bellyoshi

ログメッセージ

add newfile

変更サマリ

差分

--- trunk/crowbar/ver0.1/CRB.h (nonexistent)
+++ trunk/crowbar/ver0.1/CRB.h (revision 31)
@@ -0,0 +1,12 @@
1+#ifndef PUBLIC_CRB_H_INCLUDED
2+#define PUBLIC_CRB_H_INCLUDED
3+#include <stdio.h>
4+
5+typedef struct CRB_Interpreter_tag CRB_Interpreter;
6+
7+CRB_Interpreter *CRB_create_interpreter(void);
8+void CRB_compile(CRB_Interpreter *interpreter, FILE *fp);
9+void CRB_interpret(CRB_Interpreter *interpreter);
10+void CRB_dispose_interpreter(CRB_Interpreter *interpreter);
11+
12+#endif /* PUBLIC_CRB_H_INCLUDED */
--- trunk/crowbar/ver0.1/CRB_dev.h (nonexistent)
+++ trunk/crowbar/ver0.1/CRB_dev.h (revision 31)
@@ -0,0 +1,49 @@
1+#ifndef PUBLIC_CRB_DEV_H_INCLUDED
2+#define PUBLIC_CRB_DEV_H_INCLUDED
3+#include "CRB.h"
4+
5+typedef enum {
6+ CRB_FALSE = 0,
7+ CRB_TRUE = 1
8+} CRB_Boolean;
9+
10+typedef struct CRB_String_tag CRB_String;
11+
12+typedef struct {
13+ char *name;
14+} CRB_NativePointerInfo;
15+
16+typedef enum {
17+ CRB_BOOLEAN_VALUE = 1,
18+ CRB_INT_VALUE,
19+ CRB_DOUBLE_VALUE,
20+ CRB_STRING_VALUE,
21+ CRB_NATIVE_POINTER_VALUE,
22+ CRB_NULL_VALUE
23+} CRB_ValueType;
24+
25+typedef struct {
26+ CRB_NativePointerInfo *info;
27+ void *pointer;
28+} CRB_NativePointer;
29+
30+typedef struct {
31+ CRB_ValueType type;
32+ union {
33+ CRB_Boolean boolean_value;
34+ int int_value;
35+ double double_value;
36+ CRB_String *string_value;
37+ CRB_NativePointer native_pointer;
38+ } u;
39+} CRB_Value;
40+
41+typedef CRB_Value CRB_NativeFunctionProc(CRB_Interpreter *interpreter,
42+ int arg_count, CRB_Value *args);
43+
44+void CRB_add_native_function(CRB_Interpreter *interpreter,
45+ char *name, CRB_NativeFunctionProc *proc);
46+void CRB_add_global_variable(CRB_Interpreter *inter,
47+ char *identifier, CRB_Value *value);
48+
49+#endif /* PUBLIC_CRB_DEV_H_INCLUDED */
--- trunk/crowbar/ver0.1/DBG.h (nonexistent)
+++ trunk/crowbar/ver0.1/DBG.h (revision 31)
@@ -0,0 +1,54 @@
1+#ifndef PUBLIC_DBG_H_INCLUDED
2+#define PUBLIC_DBG_H_INCLUDED
3+#include <stdio.h>
4+#include <stdarg.h>
5+
6+typedef struct DBG_Controller_tag *DBG_Controller;
7+void DBG_set(DBG_Controller controller, char *file, int line);
8+void DBG_set_expression(char *expression);
9+
10+#ifdef DBG_NO_DEBUG
11+#define DBG_create_controller() ((void)0)
12+#define DBG_set_debug_level(level) ((void)0)
13+#define DBG_set_debug_write_fp(fp) ((void)0)
14+#define DBG_assert(expression, arg) ((void)0)
15+#define DBG_panic(arg) ((void)0)
16+#define DBG_debug_write(arg) ((void)0)
17+#else /* DBG_NO_DEBUG */
18+#ifdef DBG_CONTROLLER
19+#define DBG_CURRENT_CONTROLLER DBG_CONTROLLER
20+#else /* DBG_CONTROLLER */
21+#define DBG_CURRENT_CONTROLLER dbg_default_controller
22+#endif /* DBG_CONTROLLER */
23+extern DBG_Controller DBG_CURRENT_CONTROLLER;
24+
25+#define DBG_create_controller() (DBG_create_controller_func())
26+#define DBG_set_debug_level(level) \
27+(DBG_set_debug_level_func(DBG_CURRENT_CONTROLLER, (level)))
28+#define DBG_set_debug_write_fp(fp) \
29+(DBG_set_debug_write_fp(DBG_CURRENT_CONTROLLER, (fp))
30+#define DBG_assert(expression, arg) \
31+ ((expression) ? (void)(0) :\
32+ ((DBG_set(DBG_CURRENT_CONTROLLER, __FILE__, __LINE__)),\
33+ (DBG_set_expression(#expression)),\
34+ DBG_assert_func arg))
35+#define DBG_panic(arg) \
36+ ((DBG_set(DBG_CURRENT_CONTROLLER, __FILE__, __LINE__)),\
37+ DBG_panic_func arg)
38+#define DBG_debug_write(arg) \
39+ ((DBG_set(DBG_CURRENT_CONTROLLER, __FILE__, __LINE__)),\
40+ DBG_debug_write_func arg)
41+#endif /* DBG_NO_DEBUG */
42+
43+typedef enum {
44+ DBG_TRUE = 1,
45+ DBG_FALSE = 0
46+} DBG_Boolean;
47+
48+DBG_Controller DBG_create_controller_func(void);
49+void DBG_set_debug_level_func(DBG_Controller controller, int level);
50+void DBG_set_debug_write_fp_func(DBG_Controller controller, FILE *fp);
51+void DBG_assert_func(char *fmt, ...);
52+void DBG_panic_func(char *fmt, ...);
53+void DBG_debug_write_func(int level, char *fmt, ...);
54+#endif /* PUBLIC_DBG_H_INCLUDED */
--- trunk/crowbar/ver0.1/MEM.h (nonexistent)
+++ trunk/crowbar/ver0.1/MEM.h (revision 31)
@@ -0,0 +1,83 @@
1+#ifndef PUBLIC_MEM_H
2+#define PUBLIC_MEM_H
3+
4+#include <stdio.h>
5+#include <stdlib.h>
6+
7+typedef enum {
8+ MEM_FAIL_AND_EXIT,
9+ MEM_FAIL_AND_RETURN
10+} MEM_FailMode;
11+
12+typedef struct MEM_Controller_tag *MEM_Controller;
13+typedef void (*MEM_ErrorHandler)(MEM_Controller, char *, int, char *);
14+typedef struct MEM_Storage_tag *MEM_Storage;
15+
16+extern MEM_Controller mem_default_controller;
17+
18+#ifdef MEM_CONTROLLER
19+#define MEM_CURRENT_CONTROLLER MEM_CONTROLLER
20+#else /* MEM_CONTROLLER */
21+#define MEM_CURRENT_CONTROLLER mem_default_controller
22+#endif /* MEM_CONTROLLER */
23+
24+/*
25+ * Don't use mem_*_func function.
26+ * There are private functions of MEM module.
27+ */
28+MEM_Controller MEM_create_controller(void);
29+void *MEM_malloc_func(MEM_Controller controller,
30+ char *filename, int line, size_t size);
31+void *MEM_realloc_func(MEM_Controller controller,
32+ char *filename, int line, void *ptr, size_t size);
33+char *MEM_strdup_func(MEM_Controller controller,
34+ char *filename, int line, char *str);
35+MEM_Storage MEM_open_storage_func(MEM_Controller controller,
36+ char *filename, int line, int page_size);
37+void *MEM_storage_malloc_func(MEM_Controller controller,
38+ char *filename, int line,
39+ MEM_Storage storage, size_t size);
40+void MEM_free_func(MEM_Controller controller, void *ptr);
41+void MEM_dispose_storage_func(MEM_Controller controller,
42+ MEM_Storage storage);
43+
44+void MEM_set_error_handler(MEM_Controller controller,
45+ MEM_ErrorHandler handler);
46+void MEM_set_fail_mode(MEM_Controller controller,
47+ MEM_FailMode mode);
48+void MEM_dump_blocks_func(MEM_Controller controller, FILE *fp);
49+void MEM_check_block_func(MEM_Controller controller,
50+ char *filename, int line, void *p);
51+void MEM_check_all_blocks_func(MEM_Controller controller,
52+ char *filename, int line);
53+
54+#define MEM_malloc(size)\
55+ (MEM_malloc_func(MEM_CURRENT_CONTROLLER,\
56+ __FILE__, __LINE__, size))
57+#define MEM_realloc(ptr, size)\
58+ (MEM_realloc_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__, ptr, size))
59+#define MEM_strdup(str)\
60+ (MEM_strdup_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__, str))
61+#define MEM_open_storage(page_size)\
62+ (MEM_open_storage_func(MEM_CURRENT_CONTROLLER,\
63+ __FILE__, __LINE__, page_size))
64+#define MEM_storage_malloc(storage, size)\
65+ (MEM_storage_malloc_func(MEM_CURRENT_CONTROLLER,\
66+ __FILE__, __LINE__, storage, size))
67+#define MEM_free(ptr) (MEM_free_func(MEM_CURRENT_CONTROLLER, ptr))
68+#define MEM_dispose_storage(storage)\
69+ (MEM_dispose_storage_func(MEM_CURRENT_CONTROLLER, storage))
70+#ifdef DEBUG
71+#define MEM_dump_blocks(fp)\
72+ (MEM_dump_blocks_func(MEM_CURRENT_CONTROLLER, fp))
73+#define MEM_check_block(p)\
74+ (MEM_check_block_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__, p))
75+#define MEM_check_all_blocks()\
76+ (MEM_check_all_blocks_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__))
77+#else /* DEBUG */
78+#define MEM_dump_blocks(fp) ((void)0)
79+#define MEM_check_block(p) ((void)0)
80+#define MEM_check_all_blocks() ((void)0)
81+#endif /* DEBUG */
82+
83+#endif /* PUBLIC_MEM_H */
--- trunk/crowbar/ver0.1/Makefile (nonexistent)
+++ trunk/crowbar/ver0.1/Makefile (revision 31)
@@ -0,0 +1,54 @@
1+TARGET = crowbar
2+OBJS = \
3+ lex.yy.o\
4+ y.tab.o\
5+ main.o\
6+ interface.o\
7+ create.o\
8+ execute.o\
9+ eval.o\
10+ string.o\
11+ string_pool.o\
12+ util.o\
13+ native.o\
14+ error.o\
15+ error_message.o\
16+ ./memory/mem.o\
17+ ./debug/dbg.o
18+CFLAGS = -c -g -Wall -Wswitch-enum -ansi -pedantic -DDEBUG
19+INCLUDES = \
20+
21+$(TARGET):$(OBJS)
22+ cd ./memory; $(MAKE);
23+ cd ./debug; $(MAKE);
24+ $(CC) $(OBJS) -o $@ -lm
25+clean:
26+ rm -f *.o lex.yy.c y.tab.c y.tab.h *~
27+y.tab.h : crowbar.y
28+ yacc -dv crowbar.y
29+y.tab.c : crowbar.y
30+ yacc -dv crowbar.y
31+lex.yy.c : crowbar.l crowbar.y y.tab.h
32+ lex crowbar.l
33+y.tab.o: y.tab.c crowbar.h MEM.h
34+ $(CC) -c -g $*.c $(INCLUDES)
35+lex.yy.o: lex.yy.c crowbar.h MEM.h
36+ $(CC) -c -g $*.c $(INCLUDES)
37+.c.o:
38+ $(CC) $(CFLAGS) $*.c $(INCLUDES)
39+./memory/mem.o:
40+ cd ./memory; $(MAKE);
41+./debug/dbg.o:
42+ cd ./debug; $(MAKE);
43+############################################################
44+create.o: create.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
45+error.o: error.c MEM.h crowbar.h CRB.h CRB_dev.h
46+error_message.o: error_message.c crowbar.h MEM.h CRB.h CRB_dev.h
47+eval.o: eval.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
48+execute.o: execute.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
49+interface.o: interface.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
50+main.o: main.c CRB.h MEM.h
51+native.o: native.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
52+string.o: string.c MEM.h crowbar.h CRB.h CRB_dev.h
53+string_pool.o: string_pool.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
54+util.o: util.c MEM.h DBG.h crowbar.h CRB.h CRB_dev.h
--- trunk/crowbar/ver0.1/create.c (nonexistent)
+++ trunk/crowbar/ver0.1/create.c (revision 31)
@@ -0,0 +1,392 @@
1+#include "MEM.h"
2+#include "DBG.h"
3+#include "crowbar.h"
4+
5+void
6+crb_function_define(char *identifier, ParameterList *parameter_list,
7+ Block *block)
8+{
9+ FunctionDefinition *f;
10+ CRB_Interpreter *inter;
11+
12+ if (crb_search_function(identifier)) {
13+ crb_compile_error(FUNCTION_MULTIPLE_DEFINE_ERR,
14+ STRING_MESSAGE_ARGUMENT, "name", identifier,
15+ MESSAGE_ARGUMENT_END);
16+ return;
17+ }
18+ inter = crb_get_current_interpreter();
19+
20+ f = crb_malloc(sizeof(FunctionDefinition));
21+ f->name = identifier;
22+ f->type = CROWBAR_FUNCTION_DEFINITION;
23+ f->u.crowbar_f.parameter = parameter_list;
24+ f->u.crowbar_f.block = block;
25+ f->next = inter->function_list;
26+ inter->function_list = f;
27+}
28+
29+ParameterList *
30+crb_create_parameter(char *identifier)
31+{
32+ ParameterList *p;
33+
34+ p = crb_malloc(sizeof(ParameterList));
35+ p->name = identifier;
36+ p->next = NULL;
37+
38+ return p;
39+}
40+
41+ParameterList *
42+crb_chain_parameter(ParameterList *list, char *identifier)
43+{
44+ ParameterList *pos;
45+
46+ for (pos = list; pos->next; pos = pos->next)
47+ ;
48+ pos->next = crb_create_parameter(identifier);
49+
50+ return list;
51+}
52+
53+ArgumentList *
54+crb_create_argument_list(Expression *expression)
55+{
56+ ArgumentList *al;
57+
58+ al = crb_malloc(sizeof(ArgumentList));
59+ al->expression = expression;
60+ al->next = NULL;
61+
62+ return al;
63+}
64+
65+ArgumentList *
66+crb_chain_argument_list(ArgumentList *list, Expression *expr)
67+{
68+ ArgumentList *pos;
69+
70+ for (pos = list; pos->next; pos = pos->next)
71+ ;
72+ pos->next = crb_create_argument_list(expr);
73+
74+ return list;
75+}
76+
77+StatementList *
78+crb_create_statement_list(Statement *statement)
79+{
80+ StatementList *sl;
81+
82+ sl = crb_malloc(sizeof(StatementList));
83+ sl->statement = statement;
84+ sl->next = NULL;
85+
86+ return sl;
87+}
88+
89+StatementList *
90+crb_chain_statement_list(StatementList *list, Statement *statement)
91+{
92+ StatementList *pos;
93+
94+ if (list == NULL)
95+ return crb_create_statement_list(statement);
96+
97+ for (pos = list; pos->next; pos = pos->next)
98+ ;
99+ pos->next = crb_create_statement_list(statement);
100+
101+ return list;
102+}
103+
104+Expression *
105+crb_alloc_expression(ExpressionType type)
106+{
107+ Expression *exp;
108+
109+ exp = crb_malloc(sizeof(Expression));
110+ exp->type = type;
111+ exp->line_number = crb_get_current_interpreter()->current_line_number;
112+
113+ return exp;
114+}
115+
116+Expression *
117+crb_create_assign_expression(char *variable, Expression *operand)
118+{
119+ Expression *exp;
120+
121+ exp = crb_alloc_expression(ASSIGN_EXPRESSION);
122+ exp->u.assign_expression.variable = variable;
123+ exp->u.assign_expression.operand = operand;
124+
125+ return exp;
126+}
127+
128+static Expression
129+convert_value_to_expression(CRB_Value *v)
130+{
131+ Expression expr;
132+
133+ if (v->type == CRB_INT_VALUE) {
134+ expr.type = INT_EXPRESSION;
135+ expr.u.int_value = v->u.int_value;
136+ } else if (v->type == CRB_DOUBLE_VALUE) {
137+ expr.type = DOUBLE_EXPRESSION;
138+ expr.u.double_value = v->u.double_value;
139+ } else {
140+ DBG_assert(v->type == CRB_BOOLEAN_VALUE,
141+ ("v->type..%d\n", v->type));
142+ expr.type = BOOLEAN_EXPRESSION;
143+ expr.u.boolean_value = v->u.boolean_value;
144+ }
145+ return expr;
146+}
147+
148+Expression *
149+crb_create_binary_expression(ExpressionType operator,
150+ Expression *left, Expression *right)
151+{
152+ if ((left->type == INT_EXPRESSION
153+ || left->type == DOUBLE_EXPRESSION)
154+ && (right->type == INT_EXPRESSION
155+ || right->type == DOUBLE_EXPRESSION)) {
156+ CRB_Value v;
157+ v = crb_eval_binary_expression(crb_get_current_interpreter(),
158+ NULL, operator, left, right);
159+ /* Overwriting left hand expression. */
160+ *left = convert_value_to_expression(&v);
161+
162+ return left;
163+ } else {
164+ Expression *exp;
165+ exp = crb_alloc_expression(operator);
166+ exp->u.binary_expression.left = left;
167+ exp->u.binary_expression.right = right;
168+ return exp;
169+ }
170+}
171+
172+Expression *
173+crb_create_minus_expression(Expression *operand)
174+{
175+ if (operand->type == INT_EXPRESSION
176+ || operand->type == DOUBLE_EXPRESSION) {
177+ CRB_Value v;
178+ v = crb_eval_minus_expression(crb_get_current_interpreter(),
179+ NULL, operand);
180+ /* Notice! Overwriting operand expression. */
181+ *operand = convert_value_to_expression(&v);
182+ return operand;
183+ } else {
184+ Expression *exp;
185+ exp = crb_alloc_expression(MINUS_EXPRESSION);
186+ exp->u.minus_expression = operand;
187+ return exp;
188+ }
189+}
190+
191+Expression *
192+crb_create_identifier_expression(char *identifier)
193+{
194+ Expression *exp;
195+
196+ exp = crb_alloc_expression(IDENTIFIER_EXPRESSION);
197+ exp->u.identifier = identifier;
198+
199+ return exp;
200+}
201+
202+Expression *
203+crb_create_function_call_expression(char *func_name, ArgumentList *argument)
204+{
205+ Expression *exp;
206+
207+ exp = crb_alloc_expression(FUNCTION_CALL_EXPRESSION);
208+ exp->u.function_call_expression.identifier = func_name;
209+ exp->u.function_call_expression.argument = argument;
210+
211+ return exp;
212+}
213+
214+Expression *
215+crb_create_boolean_expression(CRB_Boolean value)
216+{
217+ Expression *exp;
218+
219+ exp = crb_alloc_expression(BOOLEAN_EXPRESSION);
220+ exp->u.boolean_value = value;
221+
222+ return exp;
223+}
224+
225+Expression *
226+crb_create_null_expression(void)
227+{
228+ Expression *exp;
229+
230+ exp = crb_alloc_expression(NULL_EXPRESSION);
231+
232+ return exp;
233+}
234+
235+static Statement *
236+alloc_statement(StatementType type)
237+{
238+ Statement *st;
239+
240+ st = crb_malloc(sizeof(Statement));
241+ st->type = type;
242+ st->line_number = crb_get_current_interpreter()->current_line_number;
243+
244+ return st;
245+}
246+
247+Statement *
248+crb_create_global_statement(IdentifierList *identifier_list)
249+{
250+ Statement *st;
251+
252+ st = alloc_statement(GLOBAL_STATEMENT);
253+ st->u.global_s.identifier_list = identifier_list;
254+
255+ return st;
256+}
257+
258+IdentifierList *
259+crb_create_global_identifier(char *identifier)
260+{
261+ IdentifierList *i_list;
262+
263+ i_list = crb_malloc(sizeof(IdentifierList));
264+ i_list->name = identifier;
265+ i_list->next = NULL;
266+
267+ return i_list;
268+}
269+
270+IdentifierList *
271+crb_chain_identifier(IdentifierList *list, char *identifier)
272+{
273+ IdentifierList *pos;
274+
275+ for (pos = list; pos->next; pos = pos->next)
276+ ;
277+ pos->next = crb_create_global_identifier(identifier);
278+
279+ return list;
280+}
281+
282+Statement *
283+crb_create_if_statement(Expression *condition,
284+ Block *then_block, Elsif *elsif_list,
285+ Block *else_block)
286+{
287+ Statement *st;
288+
289+ st = alloc_statement(IF_STATEMENT);
290+ st->u.if_s.condition = condition;
291+ st->u.if_s.then_block = then_block;
292+ st->u.if_s.elsif_list = elsif_list;
293+ st->u.if_s.else_block = else_block;
294+
295+ return st;
296+}
297+
298+Elsif *
299+crb_chain_elsif_list(Elsif *list, Elsif *add)
300+{
301+ Elsif *pos;
302+
303+ for (pos = list; pos->next; pos = pos->next)
304+ ;
305+ pos->next = add;
306+
307+ return list;
308+}
309+
310+Elsif *
311+crb_create_elsif(Expression *expr, Block *block)
312+{
313+ Elsif *ei;
314+
315+ ei = crb_malloc(sizeof(Elsif));
316+ ei->condition = expr;
317+ ei->block = block;
318+ ei->next = NULL;
319+
320+ return ei;
321+}
322+
323+Statement *
324+crb_create_while_statement(Expression *condition, Block *block)
325+{
326+ Statement *st;
327+
328+ st = alloc_statement(WHILE_STATEMENT);
329+ st->u.while_s.condition = condition;
330+ st->u.while_s.block = block;
331+
332+ return st;
333+}
334+
335+Statement *
336+crb_create_for_statement(Expression *init, Expression *cond,
337+ Expression *post, Block *block)
338+{
339+ Statement *st;
340+
341+ st = alloc_statement(FOR_STATEMENT);
342+ st->u.for_s.init = init;
343+ st->u.for_s.condition = cond;
344+ st->u.for_s.post = post;
345+ st->u.for_s.block = block;
346+
347+ return st;
348+}
349+
350+Block *
351+crb_create_block(StatementList *statement_list)
352+{
353+ Block *block;
354+
355+ block = crb_malloc(sizeof(Block));
356+ block->statement_list = statement_list;
357+
358+ return block;
359+}
360+
361+Statement *
362+crb_create_expression_statement(Expression *expression)
363+{
364+ Statement *st;
365+
366+ st = alloc_statement(EXPRESSION_STATEMENT);
367+ st->u.expression_s = expression;
368+
369+ return st;
370+}
371+
372+Statement *
373+crb_create_return_statement(Expression *expression)
374+{
375+ Statement *st;
376+
377+ st = alloc_statement(RETURN_STATEMENT);
378+ st->u.return_s.return_value = expression;
379+
380+ return st;
381+}
382+
383+Statement *crb_create_break_statement(void)
384+{
385+ return alloc_statement(BREAK_STATEMENT);
386+}
387+
388+Statement *crb_create_continue_statement(void)
389+{
390+ return alloc_statement(CONTINUE_STATEMENT);
391+}
392+
--- trunk/crowbar/ver0.1/crowbar.h (nonexistent)
+++ trunk/crowbar/ver0.1/crowbar.h (revision 31)
@@ -0,0 +1,384 @@
1+#ifndef PRIVATE_CROWBAR_H_INCLUDED
2+#define PRIVATE_CROWBAR_H_INCLUDED
3+#include <stdio.h>
4+#include "MEM.h"
5+#include "CRB.h"
6+#include "CRB_dev.h"
7+
8+#define smaller(a, b) ((a) < (b) ? (a) : (b))
9+#define larger(a, b) ((a) > (b) ? (a) : (b))
10+
11+#define MESSAGE_ARGUMENT_MAX (256)
12+#define LINE_BUF_SIZE (1024)
13+
14+typedef enum {
15+ PARSE_ERR = 1,
16+ CHARACTER_INVALID_ERR,
17+ FUNCTION_MULTIPLE_DEFINE_ERR,
18+ COMPILE_ERROR_COUNT_PLUS_1
19+} CompileError;
20+
21+typedef enum {
22+ VARIABLE_NOT_FOUND_ERR = 1,
23+ FUNCTION_NOT_FOUND_ERR,
24+ ARGUMENT_TOO_MANY_ERR,
25+ ARGUMENT_TOO_FEW_ERR,
26+ NOT_BOOLEAN_TYPE_ERR,
27+ MINUS_OPERAND_TYPE_ERR,
28+ BAD_OPERAND_TYPE_ERR,
29+ NOT_BOOLEAN_OPERATOR_ERR,
30+ FOPEN_ARGUMENT_TYPE_ERR,
31+ FCLOSE_ARGUMENT_TYPE_ERR,
32+ FGETS_ARGUMENT_TYPE_ERR,
33+ FPUTS_ARGUMENT_TYPE_ERR,
34+ NOT_NULL_OPERATOR_ERR,
35+ DIVISION_BY_ZERO_ERR,
36+ GLOBAL_VARIABLE_NOT_FOUND_ERR,
37+ GLOBAL_STATEMENT_IN_TOPLEVEL_ERR,
38+ BAD_OPERATOR_FOR_STRING_ERR,
39+ RUNTIME_ERROR_COUNT_PLUS_1
40+} RuntimeError;
41+
42+typedef enum {
43+ INT_MESSAGE_ARGUMENT = 1,
44+ DOUBLE_MESSAGE_ARGUMENT,
45+ STRING_MESSAGE_ARGUMENT,
46+ CHARACTER_MESSAGE_ARGUMENT,
47+ POINTER_MESSAGE_ARGUMENT,
48+ MESSAGE_ARGUMENT_END
49+} MessageArgumentType;
50+
51+typedef struct {
52+ char *format;
53+} MessageFormat;
54+
55+typedef struct Expression_tag Expression;
56+
57+typedef enum {
58+ BOOLEAN_EXPRESSION = 1,
59+ INT_EXPRESSION,
60+ DOUBLE_EXPRESSION,
61+ STRING_EXPRESSION,
62+ IDENTIFIER_EXPRESSION,
63+ ASSIGN_EXPRESSION,
64+ ADD_EXPRESSION,
65+ SUB_EXPRESSION,
66+ MUL_EXPRESSION,
67+ DIV_EXPRESSION,
68+ MOD_EXPRESSION,
69+ EQ_EXPRESSION,
70+ NE_EXPRESSION,
71+ GT_EXPRESSION,
72+ GE_EXPRESSION,
73+ LT_EXPRESSION,
74+ LE_EXPRESSION,
75+ LOGICAL_AND_EXPRESSION,
76+ LOGICAL_OR_EXPRESSION,
77+ MINUS_EXPRESSION,
78+ FUNCTION_CALL_EXPRESSION,
79+ NULL_EXPRESSION,
80+ EXPRESSION_TYPE_COUNT_PLUS_1
81+} ExpressionType;
82+
83+#define dkc_is_math_operator(operator) \
84+ ((operator) == ADD_EXPRESSION || (operator) == SUB_EXPRESSION\
85+ || (operator) == MUL_EXPRESSION || (operator) == DIV_EXPRESSION\
86+ || (operator) == MOD_EXPRESSION)
87+
88+#define dkc_is_compare_operator(operator) \
89+ ((operator) == EQ_EXPRESSION || (operator) == NE_EXPRESSION\
90+ || (operator) == GT_EXPRESSION || (operator) == GE_EXPRESSION\
91+ || (operator) == LT_EXPRESSION || (operator) == LE_EXPRESSION)
92+
93+#define dkc_is_logical_operator(operator) \
94+ ((operator) == LOGICAL_AND_EXPRESSION || (operator) == LOGICAL_OR_EXPRESSION)
95+
96+typedef struct ArgumentList_tag {
97+ Expression *expression;
98+ struct ArgumentList_tag *next;
99+} ArgumentList;
100+
101+typedef struct {
102+ char *variable;
103+ Expression *operand;
104+} AssignExpression;
105+
106+typedef struct {
107+ Expression *left;
108+ Expression *right;
109+} BinaryExpression;
110+
111+typedef struct {
112+ char *identifier;
113+ ArgumentList *argument;
114+} FunctionCallExpression;
115+
116+struct Expression_tag {
117+ ExpressionType type;
118+ int line_number;
119+ union {
120+ CRB_Boolean boolean_value;
121+ int int_value;
122+ double double_value;
123+ char *string_value;
124+ char *identifier;
125+ AssignExpression assign_expression;
126+ BinaryExpression binary_expression;
127+ Expression *minus_expression;
128+ FunctionCallExpression function_call_expression;
129+ } u;
130+};
131+
132+typedef struct Statement_tag Statement;
133+
134+typedef struct StatementList_tag {
135+ Statement *statement;
136+ struct StatementList_tag *next;
137+} StatementList;
138+
139+typedef struct {
140+ StatementList *statement_list;
141+} Block;
142+
143+typedef struct IdentifierList_tag {
144+ char *name;
145+ struct IdentifierList_tag *next;
146+} IdentifierList;
147+
148+typedef struct {
149+ IdentifierList *identifier_list;
150+} GlobalStatement;
151+
152+typedef struct Elsif_tag {
153+ Expression *condition;
154+ Block *block;
155+ struct Elsif_tag *next;
156+} Elsif;
157+
158+typedef struct {
159+ Expression *condition;
160+ Block *then_block;
161+ Elsif *elsif_list;
162+ Block *else_block;
163+} IfStatement;
164+
165+typedef struct {
166+ Expression *condition;
167+ Block *block;
168+} WhileStatement;
169+
170+typedef struct {
171+ Expression *init;
172+ Expression *condition;
173+ Expression *post;
174+ Block *block;
175+} ForStatement;
176+
177+typedef struct {
178+ Expression *return_value;
179+} ReturnStatement;
180+
181+typedef enum {
182+ EXPRESSION_STATEMENT = 1,
183+ GLOBAL_STATEMENT,
184+ IF_STATEMENT,
185+ WHILE_STATEMENT,
186+ FOR_STATEMENT,
187+ RETURN_STATEMENT,
188+ BREAK_STATEMENT,
189+ CONTINUE_STATEMENT,
190+ STATEMENT_TYPE_COUNT_PLUS_1
191+} StatementType;
192+
193+struct Statement_tag {
194+ StatementType type;
195+ int line_number;
196+ union {
197+ Expression *expression_s;
198+ GlobalStatement global_s;
199+ IfStatement if_s;
200+ WhileStatement while_s;
201+ ForStatement for_s;
202+ ReturnStatement return_s;
203+ } u;
204+};
205+
206+typedef struct ParameterList_tag {
207+ char *name;
208+ struct ParameterList_tag *next;
209+} ParameterList;
210+
211+typedef enum {
212+ CROWBAR_FUNCTION_DEFINITION = 1,
213+ NATIVE_FUNCTION_DEFINITION
214+} FunctionDefinitionType;
215+
216+typedef struct FunctionDefinition_tag {
217+ char *name;
218+ FunctionDefinitionType type;
219+ union {
220+ struct {
221+ ParameterList *parameter;
222+ Block *block;
223+ } crowbar_f;
224+ struct {
225+ CRB_NativeFunctionProc *proc;
226+ } native_f;
227+ } u;
228+ struct FunctionDefinition_tag *next;
229+} FunctionDefinition;
230+
231+typedef struct Variable_tag {
232+ char *name;
233+ CRB_Value value;
234+ struct Variable_tag *next;
235+} Variable;
236+
237+typedef enum {
238+ NORMAL_STATEMENT_RESULT = 1,
239+ RETURN_STATEMENT_RESULT,
240+ BREAK_STATEMENT_RESULT,
241+ CONTINUE_STATEMENT_RESULT,
242+ STATEMENT_RESULT_TYPE_COUNT_PLUS_1
243+} StatementResultType;
244+
245+typedef struct {
246+ StatementResultType type;
247+ union {
248+ CRB_Value return_value;
249+ } u;
250+} StatementResult;
251+
252+typedef struct GlobalVariableRef_tag {
253+ Variable *variable;
254+ struct GlobalVariableRef_tag *next;
255+} GlobalVariableRef;
256+
257+typedef struct {
258+ Variable *variable;
259+ GlobalVariableRef *global_variable;
260+} LocalEnvironment;
261+
262+struct CRB_String_tag {
263+ int ref_count;
264+ char *string;
265+ CRB_Boolean is_literal;
266+};
267+
268+typedef struct {
269+ CRB_String *strings;
270+} StringPool;
271+
272+struct CRB_Interpreter_tag {
273+ MEM_Storage interpreter_storage;
274+ MEM_Storage execute_storage;
275+ Variable *variable;
276+ FunctionDefinition *function_list;
277+ StatementList *statement_list;
278+ int current_line_number;
279+};
280+
281+
282+/* create.c */
283+void crb_function_define(char *identifier, ParameterList *parameter_list,
284+ Block *block);
285+ParameterList *crb_create_parameter(char *identifier);
286+ParameterList *crb_chain_parameter(ParameterList *list,
287+ char *identifier);
288+ArgumentList *crb_create_argument_list(Expression *expression);
289+ArgumentList *crb_chain_argument_list(ArgumentList *list, Expression *expr);
290+StatementList *crb_create_statement_list(Statement *statement);
291+StatementList *crb_chain_statement_list(StatementList *list,
292+ Statement *statement);
293+Expression *crb_alloc_expression(ExpressionType type);
294+Expression *crb_create_assign_expression(char *variable,
295+ Expression *operand);
296+Expression *crb_create_binary_expression(ExpressionType operator,
297+ Expression *left,
298+ Expression *right);
299+Expression *crb_create_minus_expression(Expression *operand);
300+Expression *crb_create_identifier_expression(char *identifier);
301+Expression *crb_create_function_call_expression(char *func_name,
302+ ArgumentList *argument);
303+Expression *crb_create_boolean_expression(CRB_Boolean value);
304+Expression *crb_create_null_expression(void);
305+Statement *crb_create_global_statement(IdentifierList *identifier_list);
306+IdentifierList *crb_create_global_identifier(char *identifier);
307+IdentifierList *crb_chain_identifier(IdentifierList *list, char *identifier);
308+Statement *crb_create_if_statement(Expression *condition,
309+ Block *then_block, Elsif *elsif_list,
310+ Block *else_block);
311+Elsif *crb_chain_elsif_list(Elsif *list, Elsif *add);
312+Elsif *crb_create_elsif(Expression *expr, Block *block);
313+Statement *crb_create_while_statement(Expression *condition, Block *block);
314+Statement *crb_create_for_statement(Expression *init, Expression *cond,
315+ Expression *post, Block *block);
316+Block *crb_create_block(StatementList *statement_list);
317+Statement *crb_create_expression_statement(Expression *expression);
318+Statement *crb_create_return_statement(Expression *expression);
319+Statement *crb_create_break_statement(void);
320+Statement *crb_create_continue_statement(void);
321+
322+/* string.c */
323+char *crb_create_identifier(char *str);
324+void crb_open_string_literal(void);
325+void crb_add_string_literal(int letter);
326+void crb_reset_string_literal_buffer(void);
327+char *crb_close_string_literal(void);
328+
329+/* execute.c */
330+StatementResult
331+crb_execute_statement_list(CRB_Interpreter *inter,
332+ LocalEnvironment *env, StatementList *list);
333+
334+/* eval.c */
335+CRB_Value crb_eval_binary_expression(CRB_Interpreter *inter,
336+ LocalEnvironment *env,
337+ ExpressionType operator,
338+ Expression *left, Expression *right);
339+CRB_Value crb_eval_minus_expression(CRB_Interpreter *inter,
340+ LocalEnvironment *env, Expression *operand);
341+CRB_Value crb_eval_expression(CRB_Interpreter *inter,
342+ LocalEnvironment *env, Expression *expr);
343+
344+/* string_pool.c */
345+CRB_String *crb_literal_to_crb_string(CRB_Interpreter *inter, char *str);
346+void crb_refer_string(CRB_String *str);
347+void crb_release_string(CRB_String *str);
348+CRB_String *crb_search_crb_string(CRB_Interpreter *inter, char *str);
349+CRB_String *crb_create_crowbar_string(CRB_Interpreter *inter, char *str);
350+
351+/* util.c */
352+CRB_Interpreter *crb_get_current_interpreter(void);
353+void crb_set_current_interpreter(CRB_Interpreter *inter);
354+void *crb_malloc(size_t size);
355+void *crb_execute_malloc(CRB_Interpreter *inter, size_t size);
356+Variable *crb_search_local_variable(LocalEnvironment *env,
357+ char *identifier);
358+Variable *
359+crb_search_global_variable(CRB_Interpreter *inter, char *identifier);
360+void crb_add_local_variable(LocalEnvironment *env,
361+ char *identifier, CRB_Value *value);
362+CRB_NativeFunctionProc *
363+crb_search_native_function(CRB_Interpreter *inter, char *name);
364+FunctionDefinition *crb_search_function(char *name);
365+char *crb_get_operator_string(ExpressionType type);
366+
367+/* error.c */
368+void crb_compile_error(CompileError id, ...);
369+void crb_runtime_error(int line_number, RuntimeError id, ...);
370+
371+/* native.c */
372+CRB_Value crb_nv_print_proc(CRB_Interpreter *interpreter,
373+ int arg_count, CRB_Value *args);
374+CRB_Value crb_nv_fopen_proc(CRB_Interpreter *interpreter,
375+ int arg_count, CRB_Value *args);
376+CRB_Value crb_nv_fclose_proc(CRB_Interpreter *interpreter,
377+ int arg_count, CRB_Value *args);
378+CRB_Value crb_nv_fgets_proc(CRB_Interpreter *interpreter,
379+ int arg_count, CRB_Value *args);
380+CRB_Value crb_nv_fputs_proc(CRB_Interpreter *interpreter,
381+ int arg_count, CRB_Value *args);
382+void crb_add_std_fp(CRB_Interpreter *inter);
383+
384+#endif /* PRIVATE_CROWBAR_H_INCLUDED */
--- trunk/crowbar/ver0.1/crowbar.l (nonexistent)
+++ trunk/crowbar/ver0.1/crowbar.l (revision 31)
@@ -0,0 +1,113 @@
1+%{
2+#include <stdio.h>
3+#include <string.h>
4+#include "DBG.h"
5+#include "crowbar.h"
6+#include "y.tab.h"
7+
8+int
9+yywrap(void)
10+{
11+ return 1;
12+}
13+
14+static void
15+increment_line_number(void)
16+{
17+ crb_get_current_interpreter()->current_line_number++;
18+}
19+%}
20+%start COMMENT STRING_LITERAL_STATE
21+%%
22+<INITIAL>"function" return FUNCTION;
23+<INITIAL>"if" return IF;
24+<INITIAL>"else" return ELSE;
25+<INITIAL>"elsif" return ELSIF;
26+<INITIAL>"while" return WHILE;
27+<INITIAL>"for" return FOR;
28+<INITIAL>"return" return RETURN_T;
29+<INITIAL>"break" return BREAK;
30+<INITIAL>"continue" return CONTINUE;
31+<INITIAL>"null" return NULL_T;
32+<INITIAL>"true" return TRUE_T;
33+<INITIAL>"false" return FALSE_T;
34+<INITIAL>"global" return GLOBAL_T;
35+<INITIAL>"(" return LP;
36+<INITIAL>")" return RP;
37+<INITIAL>"{" return LC;
38+<INITIAL>"}" return RC;
39+<INITIAL>";" return SEMICOLON;
40+<INITIAL>"," return COMMA;
41+<INITIAL>"&&" return LOGICAL_AND;
42+<INITIAL>"||" return LOGICAL_OR;
43+<INITIAL>"=" return ASSIGN;
44+<INITIAL>"==" return EQ;
45+<INITIAL>"!=" return NE;
46+<INITIAL>">" return GT;
47+<INITIAL>">=" return GE;
48+<INITIAL>"<" return LT;
49+<INITIAL>"<=" return LE;
50+<INITIAL>"+" return ADD;
51+<INITIAL>"-" return SUB;
52+<INITIAL>"*" return MUL;
53+<INITIAL>"/" return DIV;
54+<INITIAL>"%" return MOD;
55+<INITIAL>[A-Za-z_][A-Za-z_0-9]* {
56+ yylval.identifier = crb_create_identifier(yytext);
57+ return IDENTIFIER;
58+}
59+<INITIAL>([1-9][0-9]*)|"0" {
60+ Expression *expression = crb_alloc_expression(INT_EXPRESSION);
61+ sscanf(yytext, "%d", &expression->u.int_value);
62+ yylval.expression = expression;
63+ return INT_LITERAL;
64+}
65+<INITIAL>[0-9]+\.[0-9]+ {
66+ Expression *expression = crb_alloc_expression(DOUBLE_EXPRESSION);
67+ sscanf(yytext, "%lf", &expression->u.double_value);
68+ yylval.expression = expression;
69+ return DOUBLE_LITERAL;
70+}
71+<INITIAL>\" {
72+ crb_open_string_literal();
73+ BEGIN STRING_LITERAL_STATE;
74+}
75+<INITIAL>[ \t] ;
76+<INITIAL>\n {increment_line_number();}
77+<INITIAL># BEGIN COMMENT;
78+<INITIAL>. {
79+ char buf[LINE_BUF_SIZE];
80+
81+ if (isprint(yytext[0])) {
82+ buf[0] = yytext[0];
83+ buf[1] = '\0';
84+ } else {
85+ sprintf(buf, "0x%02x", (unsigned char)yytext[0]);
86+ }
87+
88+ crb_compile_error(CHARACTER_INVALID_ERR,
89+ STRING_MESSAGE_ARGUMENT, "bad_char", buf,
90+ MESSAGE_ARGUMENT_END);
91+}
92+<COMMENT>\n {
93+ increment_line_number();
94+ BEGIN INITIAL;
95+}
96+<COMMENT>. ;
97+<STRING_LITERAL_STATE>\" {
98+ Expression *expression = crb_alloc_expression(STRING_EXPRESSION);
99+ expression->u.string_value = crb_close_string_literal();
100+ yylval.expression = expression;
101+ BEGIN INITIAL;
102+ return STRING_LITERAL;
103+}
104+<STRING_LITERAL_STATE>\n {
105+ crb_add_string_literal('\n');
106+ increment_line_number();
107+}
108+<STRING_LITERAL_STATE>\\\" crb_add_string_literal('"');
109+<STRING_LITERAL_STATE>\\n crb_add_string_literal('\n');
110+<STRING_LITERAL_STATE>\\t crb_add_string_literal('\t');
111+<STRING_LITERAL_STATE>\\\\ crb_add_string_literal('\\');
112+<STRING_LITERAL_STATE>. crb_add_string_literal(yytext[0]);
113+%%
--- trunk/crowbar/ver0.1/crowbar.y (nonexistent)
+++ trunk/crowbar/ver0.1/crowbar.y (revision 31)
@@ -0,0 +1,318 @@
1+%{
2+#include <stdio.h>
3+#include "crowbar.h"
4+#define YYDEBUG 1
5+%}
6+%union {
7+ char *identifier;
8+ ParameterList *parameter_list;
9+ ArgumentList *argument_list;
10+ Expression *expression;
11+ Statement *statement;
12+ StatementList *statement_list;
13+ Block *block;
14+ Elsif *elsif;
15+ IdentifierList *identifier_list;
16+}
17+%token <expression> INT_LITERAL
18+%token <expression> DOUBLE_LITERAL
19+%token <expression> STRING_LITERAL
20+%token <identifier> IDENTIFIER
21+%token FUNCTION IF ELSE ELSIF WHILE FOR RETURN_T BREAK CONTINUE NULL_T
22+ LP RP LC RC SEMICOLON COMMA ASSIGN LOGICAL_AND LOGICAL_OR
23+ EQ NE GT GE LT LE ADD SUB MUL DIV MOD TRUE_T FALSE_T GLOBAL_T
24+%type <parameter_list> parameter_list
25+%type <argument_list> argument_list
26+%type <expression> expression expression_opt
27+ logical_and_expression logical_or_expression
28+ equality_expression relational_expression
29+ additive_expression multiplicative_expression
30+ unary_expression primary_expression
31+%type <statement> statement global_statement
32+ if_statement while_statement for_statement
33+ return_statement break_statement continue_statement
34+%type <statement_list> statement_list
35+%type <block> block
36+%type <elsif> elsif elsif_list
37+%type <identifier_list> identifier_list
38+%%
39+translation_unit
40+ : definition_or_statement
41+ | translation_unit definition_or_statement
42+ ;
43+definition_or_statement
44+ : function_definition
45+ | statement
46+ {
47+ CRB_Interpreter *inter = crb_get_current_interpreter();
48+
49+ inter->statement_list
50+ = crb_chain_statement_list(inter->statement_list, $1);
51+ }
52+ ;
53+function_definition
54+ : FUNCTION IDENTIFIER LP parameter_list RP block
55+ {
56+ crb_function_define($2, $4, $6);
57+ }
58+ | FUNCTION IDENTIFIER LP RP block
59+ {
60+ crb_function_define($2, NULL, $5);
61+ }
62+ ;
63+parameter_list
64+ : IDENTIFIER
65+ {
66+ $$ = crb_create_parameter($1);
67+ }
68+ | parameter_list COMMA IDENTIFIER
69+ {
70+ $$ = crb_chain_parameter($1, $3);
71+ }
72+ ;
73+argument_list
74+ : expression
75+ {
76+ $$ = crb_create_argument_list($1);
77+ }
78+ | argument_list COMMA expression
79+ {
80+ $$ = crb_chain_argument_list($1, $3);
81+ }
82+ ;
83+statement_list
84+ : statement
85+ {
86+ $$ = crb_create_statement_list($1);
87+ }
88+ | statement_list statement
89+ {
90+ $$ = crb_chain_statement_list($1, $2);
91+ }
92+ ;
93+expression
94+ : logical_or_expression
95+ | IDENTIFIER ASSIGN expression
96+ {
97+ $$ = crb_create_assign_expression($1, $3);
98+ }
99+ ;
100+logical_or_expression
101+ : logical_and_expression
102+ | logical_or_expression LOGICAL_OR logical_and_expression
103+ {
104+ $$ = crb_create_binary_expression(LOGICAL_OR_EXPRESSION, $1, $3);
105+ }
106+ ;
107+logical_and_expression
108+ : equality_expression
109+ | logical_and_expression LOGICAL_AND equality_expression
110+ {
111+ $$ = crb_create_binary_expression(LOGICAL_AND_EXPRESSION, $1, $3);
112+ }
113+ ;
114+equality_expression
115+ : relational_expression
116+ | equality_expression EQ relational_expression
117+ {
118+ $$ = crb_create_binary_expression(EQ_EXPRESSION, $1, $3);
119+ }
120+ | equality_expression NE relational_expression
121+ {
122+ $$ = crb_create_binary_expression(NE_EXPRESSION, $1, $3);
123+ }
124+ ;
125+relational_expression
126+ : additive_expression
127+ | relational_expression GT additive_expression
128+ {
129+ $$ = crb_create_binary_expression(GT_EXPRESSION, $1, $3);
130+ }
131+ | relational_expression GE additive_expression
132+ {
133+ $$ = crb_create_binary_expression(GE_EXPRESSION, $1, $3);
134+ }
135+ | relational_expression LT additive_expression
136+ {
137+ $$ = crb_create_binary_expression(LT_EXPRESSION, $1, $3);
138+ }
139+ | relational_expression LE additive_expression
140+ {
141+ $$ = crb_create_binary_expression(LE_EXPRESSION, $1, $3);
142+ }
143+ ;
144+additive_expression
145+ : multiplicative_expression
146+ | additive_expression ADD multiplicative_expression
147+ {
148+ $$ = crb_create_binary_expression(ADD_EXPRESSION, $1, $3);
149+ }
150+ | additive_expression SUB multiplicative_expression
151+ {
152+ $$ = crb_create_binary_expression(SUB_EXPRESSION, $1, $3);
153+ }
154+ ;
155+multiplicative_expression
156+ : unary_expression
157+ | multiplicative_expression MUL unary_expression
158+ {
159+ $$ = crb_create_binary_expression(MUL_EXPRESSION, $1, $3);
160+ }
161+ | multiplicative_expression DIV unary_expression
162+ {
163+ $$ = crb_create_binary_expression(DIV_EXPRESSION, $1, $3);
164+ }
165+ | multiplicative_expression MOD unary_expression
166+ {
167+ $$ = crb_create_binary_expression(MOD_EXPRESSION, $1, $3);
168+ }
169+ ;
170+unary_expression
171+ : primary_expression
172+ | SUB unary_expression
173+ {
174+ $$ = crb_create_minus_expression($2);
175+ }
176+ ;
177+primary_expression
178+ : IDENTIFIER LP argument_list RP
179+ {
180+ $$ = crb_create_function_call_expression($1, $3);
181+ }
182+ | IDENTIFIER LP RP
183+ {
184+ $$ = crb_create_function_call_expression($1, NULL);
185+ }
186+ | LP expression RP
187+ {
188+ $$ = $2;
189+ }
190+ | IDENTIFIER
191+ {
192+ $$ = crb_create_identifier_expression($1);
193+ }
194+ | INT_LITERAL
195+ | DOUBLE_LITERAL
196+ | STRING_LITERAL
197+ | TRUE_T
198+ {
199+ $$ = crb_create_boolean_expression(CRB_TRUE);
200+ }
201+ | FALSE_T
202+ {
203+ $$ = crb_create_boolean_expression(CRB_FALSE);
204+ }
205+ | NULL_T
206+ {
207+ $$ = crb_create_null_expression();
208+ }
209+ ;
210+statement
211+ : expression SEMICOLON
212+ {
213+ $$ = crb_create_expression_statement($1);
214+ }
215+ | global_statement
216+ | if_statement
217+ | while_statement
218+ | for_statement
219+ | return_statement
220+ | break_statement
221+ | continue_statement
222+ ;
223+global_statement
224+ : GLOBAL_T identifier_list SEMICOLON
225+ {
226+ $$ = crb_create_global_statement($2);
227+ }
228+ ;
229+identifier_list
230+ : IDENTIFIER
231+ {
232+ $$ = crb_create_global_identifier($1);
233+ }
234+ | identifier_list COMMA IDENTIFIER
235+ {
236+ $$ = crb_chain_identifier($1, $3);
237+ }
238+ ;
239+if_statement
240+ : IF LP expression RP block
241+ {
242+ $$ = crb_create_if_statement($3, $5, NULL, NULL);
243+ }
244+ | IF LP expression RP block ELSE block
245+ {
246+ $$ = crb_create_if_statement($3, $5, NULL, $7);
247+ }
248+ | IF LP expression RP block elsif_list
249+ {
250+ $$ = crb_create_if_statement($3, $5, $6, NULL);
251+ }
252+ | IF LP expression RP block elsif_list ELSE block
253+ {
254+ $$ = crb_create_if_statement($3, $5, $6, $8);
255+ }
256+ ;
257+elsif_list
258+ : elsif
259+ | elsif_list elsif
260+ {
261+ $$ = crb_chain_elsif_list($1, $2);
262+ }
263+ ;
264+elsif
265+ : ELSIF LP expression RP block
266+ {
267+ $$ = crb_create_elsif($3, $5);
268+ }
269+ ;
270+while_statement
271+ : WHILE LP expression RP block
272+ {
273+ $$ = crb_create_while_statement($3, $5);
274+ }
275+ ;
276+for_statement
277+ : FOR LP expression_opt SEMICOLON expression_opt SEMICOLON
278+ expression_opt RP block
279+ {
280+ $$ = crb_create_for_statement($3, $5, $7, $9);
281+ }
282+ ;
283+expression_opt
284+ : /* empty */
285+ {
286+ $$ = NULL;
287+ }
288+ | expression
289+ ;
290+return_statement
291+ : RETURN_T expression_opt SEMICOLON
292+ {
293+ $$ = crb_create_return_statement($2);
294+ }
295+ ;
296+break_statement
297+ : BREAK SEMICOLON
298+ {
299+ $$ = crb_create_break_statement();
300+ }
301+ ;
302+continue_statement
303+ : CONTINUE SEMICOLON
304+ {
305+ $$ = crb_create_continue_statement();
306+ }
307+ ;
308+block
309+ : LC statement_list RC
310+ {
311+ $$ = crb_create_block($2);
312+ }
313+ | LC RC
314+ {
315+ $$ = crb_create_block(NULL);
316+ }
317+ ;
318+%%
--- trunk/crowbar/ver0.1/debug/Makefile (nonexistent)
+++ trunk/crowbar/ver0.1/debug/Makefile (revision 31)
@@ -0,0 +1,10 @@
1+TARGET = dbg.o
2+CFLAGS = -c -g -Wall -DDBG_NO_DEBUG -ansi -pedantic
3+OBJS = debug.o
4+INCLUDES = -I..
5+
6+$(TARGET):$(OBJS)
7+ ld -r -o $@ $(OBJS)
8+.c.o:
9+ $(CC) $(CFLAGS) $(INCLUDES) $*.c
10+debug.o: debug.c ../MEM.h debug.h ../DBG.h
--- trunk/crowbar/ver0.1/debug/debug.c (nonexistent)
+++ trunk/crowbar/ver0.1/debug/debug.c (revision 31)
@@ -0,0 +1,129 @@
1+#include <stdio.h>
2+#include <limits.h>
3+#include <stdlib.h>
4+#include "MEM.h"
5+#include "debug.h"
6+
7+static DBG_Controller st_current_controller;
8+static char *st_current_file_name;
9+static int st_current_line;
10+static char *st_assert_expression;
11+
12+static struct DBG_Controller_tag st_default_controller = {
13+ NULL, /*stderr,*/
14+ INT_MAX,
15+};
16+DBG_Controller dbg_default_controller = &st_default_controller;
17+
18+DBG_Controller
19+DBG_create_controller_func(void)
20+{
21+ DBG_Controller controller;
22+
23+ controller = MEM_malloc(sizeof(struct DBG_Controller_tag));
24+ controller->debug_write_fp = NULL;
25+ controller->current_debug_level = INT_MAX;
26+
27+ return controller;
28+}
29+
30+void
31+DBG_set_debug_level_func(DBG_Controller controller, int level)
32+{
33+ controller->current_debug_level = level;
34+}
35+
36+void
37+DBG_set_debug_write_fp_func(DBG_Controller controller, FILE *fp)
38+{
39+ controller->debug_write_fp = fp;
40+}
41+
42+static void
43+initialize_debug_write_fp(void)
44+{
45+ if (st_default_controller.debug_write_fp == NULL) {
46+ st_default_controller.debug_write_fp = stderr;
47+ }
48+}
49+
50+static void
51+assert_func(FILE *fp, char *file, int line, char *expression,
52+ char *fmt, va_list ap)
53+{
54+ fprintf(fp, "Assertion failure (%s) file..%s line..%d\n",
55+ expression, file, line);
56+ if (fmt) {
57+ vfprintf(fp, fmt, ap);
58+ }
59+}
60+
61+void
62+DBG_assert_func(char *fmt, ...)
63+{
64+ va_list ap;
65+
66+ va_start(ap, fmt);
67+ initialize_debug_write_fp();
68+ assert_func(st_current_controller->debug_write_fp,
69+ st_current_file_name, st_current_line,
70+ st_assert_expression, fmt, ap);
71+ assert_func(stderr,
72+ st_current_file_name, st_current_line,
73+ st_assert_expression, fmt, ap);
74+ va_end(ap);
75+ abort();
76+}
77+
78+static void
79+panic_func(FILE *fp, char *file, int line, char *fmt, va_list ap)
80+{
81+ fprintf(fp, "Panic!! file..%s line..%d\n", file, line);
82+ if (fmt) {
83+ vfprintf(fp, fmt, ap);
84+ }
85+}
86+
87+void
88+DBG_panic_func(char *fmt, ...)
89+{
90+ va_list ap;
91+
92+ va_start(ap, fmt);
93+ initialize_debug_write_fp();
94+ panic_func(st_current_controller->debug_write_fp,
95+ st_current_file_name, st_current_line, fmt, ap);
96+ panic_func(stderr, st_current_file_name, st_current_line, fmt, ap);
97+ va_end(ap);
98+ abort();
99+}
100+
101+void
102+DBG_debug_write_func(int level, char *fmt, ...)
103+{
104+ va_list ap;
105+
106+ if (level > 0 && level > st_current_controller->current_debug_level) {
107+ return;
108+ }
109+ va_start(ap, fmt);
110+ initialize_debug_write_fp();
111+ if (fmt) {
112+ vfprintf(st_current_controller->debug_write_fp, fmt, ap);
113+ }
114+ va_end(ap);
115+}
116+
117+void
118+DBG_set(DBG_Controller controller, char *file, int line)
119+{
120+ st_current_controller = controller;
121+ st_current_file_name = file;
122+ st_current_line = line;
123+}
124+
125+void
126+DBG_set_expression(char *expression)
127+{
128+ st_assert_expression = expression;
129+}
--- trunk/crowbar/ver0.1/debug/debug.h (nonexistent)
+++ trunk/crowbar/ver0.1/debug/debug.h (revision 31)
@@ -0,0 +1,11 @@
1+#ifndef PRIVATE_DBG_H_INCLUDED
2+#define PRIVATE_DBG_H_INCLUDED
3+#include <stdio.h>
4+#include "DBG.h"
5+
6+struct DBG_Controller_tag {
7+ FILE *debug_write_fp;
8+ int current_debug_level;
9+};
10+
11+#endif /* PRIVATE_DBG_H_INCLUDED */
--- trunk/crowbar/ver0.1/error.c (nonexistent)
+++ trunk/crowbar/ver0.1/error.c (revision 31)
@@ -0,0 +1,252 @@
1+#include <stdio.h>
2+#include <stdarg.h>
3+#include <string.h>
4+#include <assert.h>
5+#include "MEM.h"
6+#include "DBG.h"
7+#include "crowbar.h"
8+
9+extern char *yytext;
10+extern MessageFormat crb_compile_error_message_format[];
11+extern MessageFormat crb_runtime_error_message_format[];
12+
13+typedef struct {
14+ char *string;
15+} VString;
16+
17+static void
18+clear_v_string(VString *v)
19+{
20+ v->string = NULL;
21+}
22+
23+int
24+my_strlen(char *str)
25+{
26+ if (str == NULL) {
27+ return 0;
28+ }
29+ return strlen(str);
30+}
31+
32+static void
33+add_string(VString *v, char *str)
34+{
35+ int new_size;
36+ int old_len;
37+
38+ old_len = my_strlen(v->string);
39+ new_size = old_len + strlen(str) + 1;
40+ v->string = MEM_realloc(v->string, new_size);
41+ strcpy(&v->string[old_len], str);
42+}
43+
44+static void
45+add_character(VString *v, int ch)
46+{
47+ int current_len;
48+
49+ current_len = my_strlen(v->string);
50+ v->string = MEM_realloc(v->string, current_len + 2);
51+ v->string[current_len] = ch;
52+ v->string[current_len+1] = '\0';
53+}
54+
55+typedef struct {
56+ MessageArgumentType type;
57+ char *name;
58+ union {
59+ int int_val;
60+ double double_val;
61+ char *string_val;
62+ void *pointer_val;
63+ int character_val;
64+ } u;
65+} MessageArgument;
66+
67+static void
68+create_message_argument(MessageArgument *arg, va_list ap)
69+{
70+ int index = 0;
71+ MessageArgumentType type;
72+
73+ while ((type = va_arg(ap, MessageArgumentType)) != MESSAGE_ARGUMENT_END) {
74+ arg[index].type = type;
75+ arg[index].name = va_arg(ap, char*);
76+ switch (type) {
77+ case INT_MESSAGE_ARGUMENT:
78+ arg[index].u.int_val = va_arg(ap, int);
79+ break;
80+ case DOUBLE_MESSAGE_ARGUMENT:
81+ arg[index].u.double_val = va_arg(ap, double);
82+ break;
83+ case STRING_MESSAGE_ARGUMENT:
84+ arg[index].u.string_val = va_arg(ap, char*);
85+ break;
86+ case POINTER_MESSAGE_ARGUMENT:
87+ arg[index].u.pointer_val = va_arg(ap, void*);
88+ break;
89+ case CHARACTER_MESSAGE_ARGUMENT:
90+ arg[index].u.character_val = va_arg(ap, int);
91+ break;
92+ case MESSAGE_ARGUMENT_END:
93+ assert(0);
94+ break;
95+ default:
96+ assert(0);
97+ }
98+ index++;
99+ assert(index < MESSAGE_ARGUMENT_MAX);
100+ }
101+}
102+
103+static void
104+search_argument(MessageArgument *arg_list,
105+ char *arg_name, MessageArgument *arg)
106+{
107+ int i;
108+
109+ for (i = 0; arg_list[i].type != MESSAGE_ARGUMENT_END; i++) {
110+ if (!strcmp(arg_list[i].name, arg_name)) {
111+ *arg = arg_list[i];
112+ return;
113+ }
114+ }
115+ assert(0);
116+}
117+
118+static void
119+format_message(MessageFormat *format, VString *v, va_list ap)
120+{
121+ int i;
122+ char buf[LINE_BUF_SIZE];
123+ int arg_name_index;
124+ char arg_name[LINE_BUF_SIZE];
125+ MessageArgument arg[MESSAGE_ARGUMENT_MAX];
126+ MessageArgument cur_arg;
127+
128+ create_message_argument(arg, ap);
129+
130+ for (i = 0; format->format[i] != '\0'; i++) {
131+ if (format->format[i] != '$') {
132+ add_character(v, format->format[i]);
133+ continue;
134+ }
135+ assert(format->format[i+1] == '(');
136+ i += 2;
137+ for (arg_name_index = 0; format->format[i] != ')';
138+ arg_name_index++, i++) {
139+ arg_name[arg_name_index] = format->format[i];
140+ }
141+ arg_name[arg_name_index] = '\0';
142+ assert(format->format[i] == ')');
143+
144+ search_argument(arg, arg_name, &cur_arg);
145+ switch (cur_arg.type) {
146+ case INT_MESSAGE_ARGUMENT:
147+ sprintf(buf, "%d", cur_arg.u.int_val);
148+ add_string(v, buf);
149+ break;
150+ case DOUBLE_MESSAGE_ARGUMENT:
151+ sprintf(buf, "%f", cur_arg.u.double_val);
152+ add_string(v, buf);
153+ break;
154+ case STRING_MESSAGE_ARGUMENT:
155+ strcpy(buf, cur_arg.u.string_val);
156+ add_string(v, cur_arg.u.string_val);
157+ break;
158+ case POINTER_MESSAGE_ARGUMENT:
159+ sprintf(buf, "%p", cur_arg.u.pointer_val);
160+ add_string(v, buf);
161+ break;
162+ case CHARACTER_MESSAGE_ARGUMENT:
163+ sprintf(buf, "%c", cur_arg.u.character_val);
164+ add_string(v, buf);
165+ break;
166+ case MESSAGE_ARGUMENT_END:
167+ assert(0);
168+ break;
169+ default:
170+ assert(0);
171+ }
172+ }
173+}
174+
175+void
176+self_check()
177+{
178+ if (strcmp(crb_compile_error_message_format[0].format, "dummy") != 0) {
179+ DBG_panic(("compile error message format error.\n"));
180+ }
181+ if (strcmp(crb_compile_error_message_format
182+ [COMPILE_ERROR_COUNT_PLUS_1].format,
183+ "dummy") != 0) {
184+ DBG_panic(("compile error message format error. "
185+ "COMPILE_ERROR_COUNT_PLUS_1..%d\n",
186+ COMPILE_ERROR_COUNT_PLUS_1));
187+ }
188+ if (strcmp(crb_runtime_error_message_format[0].format, "dummy") != 0) {
189+ DBG_panic(("runtime error message format error.\n"));
190+ }
191+ if (strcmp(crb_runtime_error_message_format
192+ [RUNTIME_ERROR_COUNT_PLUS_1].format,
193+ "dummy") != 0) {
194+ DBG_panic(("runtime error message format error. "
195+ "RUNTIME_ERROR_COUNT_PLUS_1..%d\n",
196+ RUNTIME_ERROR_COUNT_PLUS_1));
197+ }
198+}
199+
200+void
201+crb_compile_error(CompileError id, ...)
202+{
203+ va_list ap;
204+ VString message;
205+ int line_number;
206+
207+ self_check();
208+ va_start(ap, id);
209+ line_number = crb_get_current_interpreter()->current_line_number;
210+ clear_v_string(&message);
211+ format_message(&crb_compile_error_message_format[id],
212+ &message, ap);
213+ fprintf(stderr, "%3d:%s\n", line_number, message.string);
214+ va_end(ap);
215+
216+ exit(1);
217+}
218+
219+void
220+crb_runtime_error(int line_number, RuntimeError id, ...)
221+{
222+ va_list ap;
223+ VString message;
224+
225+ self_check();
226+ va_start(ap, id);
227+ clear_v_string(&message);
228+ format_message(&crb_runtime_error_message_format[id],
229+ &message, ap);
230+ fprintf(stderr, "%3d:%s\n", line_number, message.string);
231+ va_end(ap);
232+
233+ exit(1);
234+}
235+
236+
237+int
238+yyerror(char const *str)
239+{
240+ char *near_token;
241+
242+ if (yytext[0] == '\0') {
243+ near_token = "EOF";
244+ } else {
245+ near_token = yytext;
246+ }
247+ crb_compile_error(PARSE_ERR,
248+ STRING_MESSAGE_ARGUMENT, "token", near_token,
249+ MESSAGE_ARGUMENT_END);
250+
251+ return 0;
252+}
--- trunk/crowbar/ver0.1/error_message.c (nonexistent)
+++ trunk/crowbar/ver0.1/error_message.c (revision 31)
@@ -0,0 +1,33 @@
1+#include <string.h>
2+#include "crowbar.h"
3+
4+MessageFormat crb_compile_error_message_format[] = {
5+ {"dummy"},
6+ {"文法エラー($(token)付近)"},
7+ {"不正な文字($(bad_char))"},
8+ {"関数名が重複しています($(name))"},
9+ {"dummy"},
10+};
11+
12+MessageFormat crb_runtime_error_message_format[] = {
13+ {"dummy"},
14+ {"変数が見つかりません($(name))。"},
15+ {"関数が見つかりません($(name))。"},
16+ {"関数が要求する引数に対し、渡している引数が多すぎます。"},
17+ {"関数が要求する引数に対し、渡している引数が少なすぎます。"},
18+ {"条件式はboolean型でなければなりません。"},
19+ {"マイナス演算子のオペランドは数値型でなければなりません。"},
20+ {"2項演算子$(operator)のオペランドの型が不正です。"},
21+ {"$(operator)演算子はboolean型には使えません。"},
22+ {"fopen()関数にはファイルのパスとモード(どちらも文字列型)を"
23+ "渡してください。"},
24+ {"fclose()関数にはファイルポインタを渡してください。"},
25+ {"fgets()関数にはファイルポインタを渡してください。"},
26+ {"fputs()関数にはファイルポインタと文字列を渡してください。"},
27+ {"nullに対して可能な演算は == と != だけです($(operator)はできません)。"},
28+ {"ゼロで除算はできません。"},
29+ {"グローバル変数$(name)は存在しません。"},
30+ {"global文は関数外では使えません。"},
31+ {"文字列に対し演算子$(operator)は適用できません。"},
32+ {"dummy"},
33+};
--- trunk/crowbar/ver0.1/eval.c (nonexistent)
+++ trunk/crowbar/ver0.1/eval.c (revision 31)
@@ -0,0 +1,747 @@
1+#include <math.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "DBG.h"
5+#include "crowbar.h"
6+
7+static CRB_Value
8+eval_boolean_expression(CRB_Boolean boolean_value)
9+{
10+ CRB_Value v;
11+
12+ v.type = CRB_BOOLEAN_VALUE;
13+ v.u.boolean_value = boolean_value;
14+
15+ return v;
16+}
17+
18+static CRB_Value
19+eval_int_expression(int int_value)
20+{
21+ CRB_Value v;
22+
23+ v.type = CRB_INT_VALUE;
24+ v.u.int_value = int_value;
25+
26+ return v;
27+}
28+
29+static CRB_Value
30+eval_double_expression(double double_value)
31+{
32+ CRB_Value v;
33+
34+ v.type = CRB_DOUBLE_VALUE;
35+ v.u.double_value = double_value;
36+
37+ return v;
38+}
39+
40+static CRB_Value
41+eval_string_expression(CRB_Interpreter *inter, char *string_value)
42+{
43+ CRB_Value v;
44+
45+ v.type = CRB_STRING_VALUE;
46+ v.u.string_value = crb_literal_to_crb_string(inter, string_value);
47+
48+ return v;
49+}
50+
51+static CRB_Value
52+eval_null_expression(void)
53+{
54+ CRB_Value v;
55+
56+ v.type = CRB_NULL_VALUE;
57+
58+ return v;
59+}
60+
61+static void
62+refer_if_string(CRB_Value *v)
63+{
64+ if (v->type == CRB_STRING_VALUE) {
65+ crb_refer_string(v->u.string_value);
66+ }
67+}
68+
69+static void
70+release_if_string(CRB_Value *v)
71+{
72+ if (v->type == CRB_STRING_VALUE) {
73+ crb_release_string(v->u.string_value);
74+ }
75+}
76+
77+static Variable *
78+search_global_variable_from_env(CRB_Interpreter *inter,
79+ LocalEnvironment *env, char *name)
80+{
81+ GlobalVariableRef *pos;
82+
83+ if (env == NULL) {
84+ return crb_search_global_variable(inter, name);
85+ }
86+
87+ for (pos = env->global_variable; pos; pos = pos->next) {
88+ if (!strcmp(pos->variable->name, name)) {
89+ return pos->variable;
90+ }
91+ }
92+
93+ return NULL;
94+}
95+
96+static CRB_Value
97+eval_identifier_expression(CRB_Interpreter *inter,
98+ LocalEnvironment *env, Expression *expr)
99+{
100+ CRB_Value v;
101+ Variable *vp;
102+
103+ vp = crb_search_local_variable(env, expr->u.identifier);
104+ if (vp != NULL) {
105+ v = vp->value;
106+ } else {
107+ vp = search_global_variable_from_env(inter, env, expr->u.identifier);
108+ if (vp != NULL) {
109+ v = vp->value;
110+ } else {
111+ crb_runtime_error(expr->line_number, VARIABLE_NOT_FOUND_ERR,
112+ STRING_MESSAGE_ARGUMENT,
113+ "name", expr->u.identifier,
114+ MESSAGE_ARGUMENT_END);
115+ }
116+ }
117+ refer_if_string(&v);
118+
119+ return v;
120+}
121+
122+static CRB_Value eval_expression(CRB_Interpreter *inter, LocalEnvironment *env,
123+ Expression *expr);
124+static CRB_Value
125+eval_assign_expression(CRB_Interpreter *inter, LocalEnvironment *env,
126+ char *identifier, Expression *expression)
127+{
128+ CRB_Value v;
129+ Variable *left;
130+
131+ v = eval_expression(inter, env, expression);
132+
133+ left = crb_search_local_variable(env, identifier);
134+ if (left == NULL) {
135+ left = search_global_variable_from_env(inter, env, identifier);
136+ }
137+ if (left != NULL) {
138+ release_if_string(&left->value);
139+ left->value = v;
140+ refer_if_string(&v);
141+ } else {
142+ if (env != NULL) {
143+ crb_add_local_variable(env, identifier, &v);
144+ } else {
145+ CRB_add_global_variable(inter, identifier, &v);
146+ }
147+ refer_if_string(&v);
148+ }
149+
150+ return v;
151+}
152+
153+static CRB_Boolean
154+eval_binary_boolean(CRB_Interpreter *inter, ExpressionType operator,
155+ CRB_Boolean left, CRB_Boolean right, int line_number)
156+{
157+ CRB_Boolean result;
158+
159+ if (operator == EQ_EXPRESSION) {
160+ result = left == right;
161+ } else if (operator == NE_EXPRESSION) {
162+ result = left != right;
163+ } else {
164+ char *op_str = crb_get_operator_string(operator);
165+ crb_runtime_error(line_number, NOT_BOOLEAN_OPERATOR_ERR,
166+ STRING_MESSAGE_ARGUMENT, "operator", op_str,
167+ MESSAGE_ARGUMENT_END);
168+ }
169+
170+ return result;
171+}
172+
173+static void
174+eval_binary_int(CRB_Interpreter *inter, ExpressionType operator,
175+ int left, int right,
176+ CRB_Value *result, int line_number)
177+{
178+ if (dkc_is_math_operator(operator)) {
179+ result->type = CRB_INT_VALUE;
180+ } else if (dkc_is_compare_operator(operator)) {
181+ result->type = CRB_BOOLEAN_VALUE;
182+ } else {
183+ DBG_panic(("operator..%d\n", operator));
184+ }
185+
186+ switch (operator) {
187+ case BOOLEAN_EXPRESSION: /* FALLTHRU */
188+ case INT_EXPRESSION: /* FALLTHRU */
189+ case DOUBLE_EXPRESSION: /* FALLTHRU */
190+ case STRING_EXPRESSION: /* FALLTHRU */
191+ case IDENTIFIER_EXPRESSION: /* FALLTHRU */
192+ case ASSIGN_EXPRESSION:
193+ DBG_panic(("bad case...%d", operator));
194+ break;
195+ case ADD_EXPRESSION:
196+ result->u.int_value = left + right;
197+ break;
198+ case SUB_EXPRESSION:
199+ result->u.int_value = left - right;
200+ break;
201+ case MUL_EXPRESSION:
202+ result->u.int_value = left * right;
203+ break;
204+ case DIV_EXPRESSION:
205+ result->u.int_value = left / right;
206+ break;
207+ case MOD_EXPRESSION:
208+ result->u.int_value = left % right;
209+ break;
210+ case LOGICAL_AND_EXPRESSION: /* FALLTHRU */
211+ case LOGICAL_OR_EXPRESSION:
212+ DBG_panic(("bad case...%d", operator));
213+ break;
214+ case EQ_EXPRESSION:
215+ result->u.boolean_value = left == right;
216+ break;
217+ case NE_EXPRESSION:
218+ result->u.boolean_value = left != right;
219+ break;
220+ case GT_EXPRESSION:
221+ result->u.boolean_value = left > right;
222+ break;
223+ case GE_EXPRESSION:
224+ result->u.boolean_value = left >= right;
225+ break;
226+ case LT_EXPRESSION:
227+ result->u.boolean_value = left < right;
228+ break;
229+ case LE_EXPRESSION:
230+ result->u.boolean_value = left <= right;
231+ break;
232+ case MINUS_EXPRESSION: /* FALLTHRU */
233+ case FUNCTION_CALL_EXPRESSION: /* FALLTHRU */
234+ case NULL_EXPRESSION: /* FALLTHRU */
235+ case EXPRESSION_TYPE_COUNT_PLUS_1: /* FALLTHRU */
236+ default:
237+ DBG_panic(("bad case...%d", operator));
238+ }
239+}
240+
241+static void
242+eval_binary_double(CRB_Interpreter *inter, ExpressionType operator,
243+ double left, double right,
244+ CRB_Value *result, int line_number)
245+{
246+ if (dkc_is_math_operator(operator)) {
247+ result->type = CRB_DOUBLE_VALUE;
248+ } else if (dkc_is_compare_operator(operator)) {
249+ result->type = CRB_BOOLEAN_VALUE;
250+ } else {
251+ DBG_panic(("operator..%d\n", operator));
252+ }
253+
254+ switch (operator) {
255+ case BOOLEAN_EXPRESSION: /* FALLTHRU */
256+ case INT_EXPRESSION: /* FALLTHRU */
257+ case DOUBLE_EXPRESSION: /* FALLTHRU */
258+ case STRING_EXPRESSION: /* FALLTHRU */
259+ case IDENTIFIER_EXPRESSION: /* FALLTHRU */
260+ case ASSIGN_EXPRESSION:
261+ DBG_panic(("bad case...%d", operator));
262+ break;
263+ case ADD_EXPRESSION:
264+ result->u.double_value = left + right;
265+ break;
266+ case SUB_EXPRESSION:
267+ result->u.double_value = left - right;
268+ break;
269+ case MUL_EXPRESSION:
270+ result->u.double_value = left * right;
271+ break;
272+ case DIV_EXPRESSION:
273+ result->u.double_value = left / right;
274+ break;
275+ case MOD_EXPRESSION:
276+ result->u.double_value = fmod(left, right);
277+ break;
278+ case LOGICAL_AND_EXPRESSION: /* FALLTHRU */
279+ case LOGICAL_OR_EXPRESSION:
280+ DBG_panic(("bad case...%d", operator));
281+ break;
282+ case EQ_EXPRESSION:
283+ result->u.int_value = left == right;
284+ break;
285+ case NE_EXPRESSION:
286+ result->u.int_value = left != right;
287+ break;
288+ case GT_EXPRESSION:
289+ result->u.int_value = left > right;
290+ break;
291+ case GE_EXPRESSION:
292+ result->u.int_value = left >= right;
293+ break;
294+ case LT_EXPRESSION:
295+ result->u.int_value = left < right;
296+ break;
297+ case LE_EXPRESSION:
298+ result->u.int_value = left <= right;
299+ break;
300+ case MINUS_EXPRESSION: /* FALLTHRU */
301+ case FUNCTION_CALL_EXPRESSION: /* FALLTHRU */
302+ case NULL_EXPRESSION: /* FALLTHRU */
303+ case EXPRESSION_TYPE_COUNT_PLUS_1: /* FALLTHRU */
304+ default:
305+ DBG_panic(("bad default...%d", operator));
306+ }
307+}
308+
309+static CRB_Boolean
310+eval_compare_string(ExpressionType operator,
311+ CRB_Value *left, CRB_Value *right, int line_number)
312+{
313+ CRB_Boolean result;
314+ int cmp;
315+
316+ cmp = strcmp(left->u.string_value->string, right->u.string_value->string);
317+
318+ if (operator == EQ_EXPRESSION) {
319+ result = (cmp == 0);
320+ } else if (operator == NE_EXPRESSION) {
321+ result = (cmp != 0);
322+ } else if (operator == GT_EXPRESSION) {
323+ result = (cmp > 0);
324+ } else if (operator == GE_EXPRESSION) {
325+ result = (cmp >= 0);
326+ } else if (operator == LT_EXPRESSION) {
327+ result = (cmp < 0);
328+ } else if (operator == LE_EXPRESSION) {
329+ result = (cmp <= 0);
330+ } else {
331+ char *op_str = crb_get_operator_string(operator);
332+ crb_runtime_error(line_number, BAD_OPERATOR_FOR_STRING_ERR,
333+ STRING_MESSAGE_ARGUMENT, "operator", op_str,
334+ MESSAGE_ARGUMENT_END);
335+ }
336+ crb_release_string(left->u.string_value);
337+ crb_release_string(right->u.string_value);
338+
339+ return result;
340+}
341+
342+static CRB_Boolean
343+eval_binary_null(CRB_Interpreter *inter, ExpressionType operator,
344+ CRB_Value *left, CRB_Value *right, int line_number)
345+{
346+ CRB_Boolean result;
347+
348+ if (operator == EQ_EXPRESSION) {
349+ result = left->type == CRB_NULL_VALUE && right->type == CRB_NULL_VALUE;
350+ } else if (operator == NE_EXPRESSION) {
351+ result = !(left->type == CRB_NULL_VALUE
352+ && right->type == CRB_NULL_VALUE);
353+ } else {
354+ char *op_str = crb_get_operator_string(operator);
355+ crb_runtime_error(line_number, NOT_NULL_OPERATOR_ERR,
356+ STRING_MESSAGE_ARGUMENT, "operator", op_str,
357+ MESSAGE_ARGUMENT_END);
358+ }
359+ release_if_string(left);
360+ release_if_string(right);
361+
362+ return result;
363+}
364+
365+CRB_String *
366+chain_string(CRB_Interpreter *inter, CRB_String *left, CRB_String *right)
367+{
368+ int len;
369+ char *str;
370+ CRB_String *ret;
371+
372+ len = strlen(left->string) + strlen(right->string);
373+ str = MEM_malloc(len + 1);
374+ strcpy(str, left->string);
375+ strcat(str, right->string);
376+ ret = crb_create_crowbar_string(inter, str);
377+ crb_release_string(left);
378+ crb_release_string(right);
379+
380+ return ret;
381+}
382+
383+CRB_Value
384+crb_eval_binary_expression(CRB_Interpreter *inter, LocalEnvironment *env,
385+ ExpressionType operator,
386+ Expression *left, Expression *right)
387+{
388+ CRB_Value left_val;
389+ CRB_Value right_val;
390+ CRB_Value result;
391+
392+ left_val = eval_expression(inter, env, left);
393+ right_val = eval_expression(inter, env, right);
394+
395+ if (left_val.type == CRB_INT_VALUE
396+ && right_val.type == CRB_INT_VALUE) {
397+ eval_binary_int(inter, operator,
398+ left_val.u.int_value, right_val.u.int_value,
399+ &result, left->line_number);
400+ } else if (left_val.type == CRB_DOUBLE_VALUE
401+ && right_val.type == CRB_DOUBLE_VALUE) {
402+ eval_binary_double(inter, operator,
403+ left_val.u.double_value, right_val.u.double_value,
404+ &result, left->line_number);
405+ } else if (left_val.type == CRB_INT_VALUE
406+ && right_val.type == CRB_DOUBLE_VALUE) {
407+ left_val.u.double_value = left_val.u.int_value;
408+ eval_binary_double(inter, operator,
409+ left_val.u.double_value, right_val.u.double_value,
410+ &result, left->line_number);
411+ } else if (left_val.type == CRB_DOUBLE_VALUE
412+ && right_val.type == CRB_INT_VALUE) {
413+ right_val.u.double_value = right_val.u.int_value;
414+ eval_binary_double(inter, operator,
415+ left_val.u.double_value, right_val.u.double_value,
416+ &result, left->line_number);
417+ } else if (left_val.type == CRB_BOOLEAN_VALUE
418+ && right_val.type == CRB_BOOLEAN_VALUE) {
419+ result.type = CRB_BOOLEAN_VALUE;
420+ result.u.boolean_value
421+ = eval_binary_boolean(inter, operator,
422+ left_val.u.boolean_value,
423+ right_val.u.boolean_value,
424+ left->line_number);
425+ } else if (left_val.type == CRB_STRING_VALUE
426+ && operator == ADD_EXPRESSION) {
427+ char buf[LINE_BUF_SIZE];
428+ CRB_String *right_str;
429+
430+ if (right_val.type == CRB_INT_VALUE) {
431+ sprintf(buf, "%d", right_val.u.int_value);
432+ right_str = crb_create_crowbar_string(inter, MEM_strdup(buf));
433+ } else if (right_val.type == CRB_DOUBLE_VALUE) {
434+ sprintf(buf, "%f", right_val.u.double_value);
435+ right_str = crb_create_crowbar_string(inter, MEM_strdup(buf));
436+ } else if (right_val.type == CRB_BOOLEAN_VALUE) {
437+ if (right_val.u.boolean_value) {
438+ right_str = crb_create_crowbar_string(inter,
439+ MEM_strdup("true"));
440+ } else {
441+ right_str = crb_create_crowbar_string(inter,
442+ MEM_strdup("false"));
443+ }
444+ } else if (right_val.type == CRB_STRING_VALUE) {
445+ right_str = right_val.u.string_value;
446+ } else if (right_val.type == CRB_NATIVE_POINTER_VALUE) {
447+ sprintf(buf, "(%s:%p)",
448+ right_val.u.native_pointer.info->name,
449+ right_val.u.native_pointer.pointer);
450+ right_str = crb_create_crowbar_string(inter, MEM_strdup(buf));
451+ } else if (right_val.type == CRB_NULL_VALUE) {
452+ right_str = crb_create_crowbar_string(inter, MEM_strdup("null"));
453+ }
454+ result.type = CRB_STRING_VALUE;
455+ result.u.string_value = chain_string(inter,
456+ left_val.u.string_value,
457+ right_str);
458+ } else if (left_val.type == CRB_STRING_VALUE
459+ && right_val.type == CRB_STRING_VALUE) {
460+ result.type = CRB_BOOLEAN_VALUE;
461+ result.u.boolean_value
462+ = eval_compare_string(operator, &left_val, &right_val,
463+ left->line_number);
464+ } else if (left_val.type == CRB_NULL_VALUE
465+ || right_val.type == CRB_NULL_VALUE) {
466+ result.type = CRB_BOOLEAN_VALUE;
467+ result.u.boolean_value
468+ = eval_binary_null(inter, operator, &left_val, &right_val,
469+ left->line_number);
470+ } else {
471+ char *op_str = crb_get_operator_string(operator);
472+ crb_runtime_error(left->line_number, BAD_OPERAND_TYPE_ERR,
473+ STRING_MESSAGE_ARGUMENT, "operator", op_str,
474+ MESSAGE_ARGUMENT_END);
475+ }
476+
477+ return result;
478+}
479+
480+static CRB_Value
481+eval_logical_and_or_expression(CRB_Interpreter *inter,
482+ LocalEnvironment *env,
483+ ExpressionType operator,
484+ Expression *left, Expression *right)
485+{
486+ CRB_Value left_val;
487+ CRB_Value right_val;
488+ CRB_Value result;
489+
490+ result.type = CRB_BOOLEAN_VALUE;
491+ left_val = eval_expression(inter, env, left);
492+
493+ if (left_val.type != CRB_BOOLEAN_VALUE) {
494+ crb_runtime_error(left->line_number, NOT_BOOLEAN_TYPE_ERR,
495+ MESSAGE_ARGUMENT_END);
496+ }
497+ if (operator == LOGICAL_AND_EXPRESSION) {
498+ if (!left_val.u.boolean_value) {
499+ result.u.boolean_value = CRB_FALSE;
500+ return result;
501+ }
502+ } else if (operator == LOGICAL_OR_EXPRESSION) {
503+ if (left_val.u.boolean_value) {
504+ result.u.boolean_value = CRB_TRUE;
505+ return result;
506+ }
507+ } else {
508+ DBG_panic(("bad operator..%d\n", operator));
509+ }
510+
511+ right_val = eval_expression(inter, env, right);
512+ if (right_val.type != CRB_BOOLEAN_VALUE) {
513+ crb_runtime_error(right->line_number, NOT_BOOLEAN_TYPE_ERR,
514+ MESSAGE_ARGUMENT_END);
515+ }
516+ result.u.boolean_value = right_val.u.boolean_value;
517+
518+ return result;
519+}
520+
521+
522+CRB_Value
523+crb_eval_minus_expression(CRB_Interpreter *inter, LocalEnvironment *env,
524+ Expression *operand)
525+{
526+ CRB_Value operand_val;
527+ CRB_Value result;
528+
529+ operand_val = eval_expression(inter, env, operand);
530+ if (operand_val.type == CRB_INT_VALUE) {
531+ result.type = CRB_INT_VALUE;
532+ result.u.int_value = -operand_val.u.int_value;
533+ } else if (operand_val.type == CRB_DOUBLE_VALUE) {
534+ result.type = CRB_DOUBLE_VALUE;
535+ result.u.double_value = -operand_val.u.double_value;
536+ } else {
537+ crb_runtime_error(operand->line_number, MINUS_OPERAND_TYPE_ERR,
538+ MESSAGE_ARGUMENT_END);
539+ }
540+ return result;
541+}
542+
543+static LocalEnvironment *
544+alloc_local_environment()
545+{
546+ LocalEnvironment *ret;
547+
548+ ret = MEM_malloc(sizeof(LocalEnvironment));
549+ ret->variable = NULL;
550+ ret->global_variable = NULL;
551+
552+ return ret;
553+}
554+
555+static void
556+dispose_local_environment(CRB_Interpreter *inter, LocalEnvironment *env)
557+{
558+ while (env->variable) {
559+ Variable *temp;
560+ temp = env->variable;
561+ if (env->variable->value.type == CRB_STRING_VALUE) {
562+ crb_release_string(env->variable->value.u.string_value);
563+ }
564+ env->variable = temp->next;
565+ MEM_free(temp);
566+ }
567+ while (env->global_variable) {
568+ GlobalVariableRef *ref;
569+ ref = env->global_variable;
570+ env->global_variable = ref->next;
571+ MEM_free(ref);
572+ }
573+
574+ MEM_free(env);
575+}
576+
577+static CRB_Value
578+call_native_function(CRB_Interpreter *inter, LocalEnvironment *env,
579+ Expression *expr, CRB_NativeFunctionProc *proc)
580+{
581+ CRB_Value value;
582+ int arg_count;
583+ ArgumentList *arg_p;
584+ CRB_Value *args;
585+ int i;
586+
587+ for (arg_count = 0, arg_p = expr->u.function_call_expression.argument;
588+ arg_p; arg_p = arg_p->next) {
589+ arg_count++;
590+ }
591+
592+ args = MEM_malloc(sizeof(CRB_Value) * arg_count);
593+
594+ for (arg_p = expr->u.function_call_expression.argument, i = 0;
595+ arg_p; arg_p = arg_p->next, i++) {
596+ args[i] = eval_expression(inter, env, arg_p->expression);
597+ }
598+ value = proc(inter, arg_count, args);
599+ for (i = 0; i < arg_count; i++) {
600+ release_if_string(&args[i]);
601+ }
602+ MEM_free(args);
603+
604+ return value;
605+}
606+
607+static CRB_Value
608+call_crowbar_function(CRB_Interpreter *inter, LocalEnvironment *env,
609+ Expression *expr, FunctionDefinition *func)
610+{
611+ CRB_Value value;
612+ StatementResult result;
613+ ArgumentList *arg_p;
614+ ParameterList *param_p;
615+ LocalEnvironment *local_env;
616+
617+ local_env = alloc_local_environment();
618+
619+ for (arg_p = expr->u.function_call_expression.argument,
620+ param_p = func->u.crowbar_f.parameter;
621+ arg_p;
622+ arg_p = arg_p->next, param_p = param_p->next) {
623+ CRB_Value arg_val;
624+
625+ if (param_p == NULL) {
626+ crb_runtime_error(expr->line_number, ARGUMENT_TOO_MANY_ERR,
627+ MESSAGE_ARGUMENT_END);
628+ }
629+ arg_val = eval_expression(inter, env, arg_p->expression);
630+ crb_add_local_variable(local_env, param_p->name, &arg_val);
631+ }
632+ if (param_p) {
633+ crb_runtime_error(expr->line_number, ARGUMENT_TOO_FEW_ERR,
634+ MESSAGE_ARGUMENT_END);
635+ }
636+ result = crb_execute_statement_list(inter, local_env,
637+ func->u.crowbar_f.block
638+ ->statement_list);
639+ if (result.type == RETURN_STATEMENT_RESULT) {
640+ value = result.u.return_value;
641+ } else {
642+ value.type = CRB_NULL_VALUE;
643+ }
644+ dispose_local_environment(inter, local_env);
645+
646+ return value;
647+}
648+
649+static CRB_Value
650+eval_function_call_expression(CRB_Interpreter *inter, LocalEnvironment *env,
651+ Expression *expr)
652+{
653+ CRB_Value value;
654+ FunctionDefinition *func;
655+
656+ char *identifier = expr->u.function_call_expression.identifier;
657+
658+ func = crb_search_function(identifier);
659+ if (func == NULL) {
660+ crb_runtime_error(expr->line_number, FUNCTION_NOT_FOUND_ERR,
661+ STRING_MESSAGE_ARGUMENT, "name", identifier,
662+ MESSAGE_ARGUMENT_END);
663+ }
664+ switch (func->type) {
665+ case CROWBAR_FUNCTION_DEFINITION:
666+ value = call_crowbar_function(inter, env, expr, func);
667+ break;
668+ case NATIVE_FUNCTION_DEFINITION:
669+ value = call_native_function(inter, env, expr, func->u.native_f.proc);
670+ break;
671+ default:
672+ DBG_panic(("bad case..%d\n", func->type));
673+ }
674+
675+ return value;
676+}
677+
678+static CRB_Value
679+eval_expression(CRB_Interpreter *inter, LocalEnvironment *env,
680+ Expression *expr)
681+{
682+ CRB_Value v;
683+ switch (expr->type) {
684+ case BOOLEAN_EXPRESSION:
685+ v = eval_boolean_expression(expr->u.boolean_value);
686+ break;
687+ case INT_EXPRESSION:
688+ v = eval_int_expression(expr->u.int_value);
689+ break;
690+ case DOUBLE_EXPRESSION:
691+ v = eval_double_expression(expr->u.double_value);
692+ break;
693+ case STRING_EXPRESSION:
694+ v = eval_string_expression(inter, expr->u.string_value);
695+ break;
696+ case IDENTIFIER_EXPRESSION:
697+ v = eval_identifier_expression(inter, env, expr);
698+ break;
699+ case ASSIGN_EXPRESSION:
700+ v = eval_assign_expression(inter, env,
701+ expr->u.assign_expression.variable,
702+ expr->u.assign_expression.operand);
703+ break;
704+ case ADD_EXPRESSION: /* FALLTHRU */
705+ case SUB_EXPRESSION: /* FALLTHRU */
706+ case MUL_EXPRESSION: /* FALLTHRU */
707+ case DIV_EXPRESSION: /* FALLTHRU */
708+ case MOD_EXPRESSION: /* FALLTHRU */
709+ case EQ_EXPRESSION: /* FALLTHRU */
710+ case NE_EXPRESSION: /* FALLTHRU */
711+ case GT_EXPRESSION: /* FALLTHRU */
712+ case GE_EXPRESSION: /* FALLTHRU */
713+ case LT_EXPRESSION: /* FALLTHRU */
714+ case LE_EXPRESSION:
715+ v = crb_eval_binary_expression(inter, env,
716+ expr->type,
717+ expr->u.binary_expression.left,
718+ expr->u.binary_expression.right);
719+ break;
720+ case LOGICAL_AND_EXPRESSION:/* FALLTHRU */
721+ case LOGICAL_OR_EXPRESSION:
722+ v = eval_logical_and_or_expression(inter, env, expr->type,
723+ expr->u.binary_expression.left,
724+ expr->u.binary_expression.right);
725+ break;
726+ case MINUS_EXPRESSION:
727+ v = crb_eval_minus_expression(inter, env, expr->u.minus_expression);
728+ break;
729+ case FUNCTION_CALL_EXPRESSION:
730+ v = eval_function_call_expression(inter, env, expr);
731+ break;
732+ case NULL_EXPRESSION:
733+ v = eval_null_expression();
734+ break;
735+ case EXPRESSION_TYPE_COUNT_PLUS_1: /* FALLTHRU */
736+ default:
737+ DBG_panic(("bad case. type..%d\n", expr->type));
738+ }
739+ return v;
740+}
741+
742+CRB_Value
743+crb_eval_expression(CRB_Interpreter *inter, LocalEnvironment *env,
744+ Expression *expr)
745+{
746+ return eval_expression(inter, env, expr);
747+}
--- trunk/crowbar/ver0.1/execute.c (nonexistent)
+++ trunk/crowbar/ver0.1/execute.c (revision 31)
@@ -0,0 +1,307 @@
1+#include <math.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "DBG.h"
5+#include "crowbar.h"
6+
7+static StatementResult
8+execute_statement(CRB_Interpreter *inter, LocalEnvironment *env,
9+ Statement *statement);
10+
11+static StatementResult
12+execute_expression_statement(CRB_Interpreter *inter, LocalEnvironment *env,
13+ Statement *statement)
14+{
15+ StatementResult result;
16+ CRB_Value v;
17+
18+ result.type = NORMAL_STATEMENT_RESULT;
19+
20+ v = crb_eval_expression(inter, env, statement->u.expression_s);
21+ if (v.type == CRB_STRING_VALUE) {
22+ crb_release_string(v.u.string_value);
23+ }
24+
25+ return result;
26+}
27+
28+static StatementResult
29+execute_global_statement(CRB_Interpreter *inter, LocalEnvironment *env,
30+ Statement *statement)
31+{
32+ IdentifierList *pos;
33+ StatementResult result;
34+
35+ result.type = NORMAL_STATEMENT_RESULT;
36+
37+ if (env == NULL) {
38+ crb_runtime_error(statement->line_number,
39+ GLOBAL_STATEMENT_IN_TOPLEVEL_ERR,
40+ MESSAGE_ARGUMENT_END);
41+ }
42+ for (pos = statement->u.global_s.identifier_list; pos; pos = pos->next) {
43+ GlobalVariableRef *ref_pos;
44+ GlobalVariableRef *new_ref;
45+ Variable *variable;
46+ for (ref_pos = env->global_variable; ref_pos;
47+ ref_pos = ref_pos->next) {
48+ if (!strcmp(ref_pos->variable->name, pos->name))
49+ goto NEXT_IDENTIFIER;
50+ }
51+ variable = crb_search_global_variable(inter, pos->name);
52+ if (variable == NULL) {
53+ crb_runtime_error(statement->line_number,
54+ GLOBAL_VARIABLE_NOT_FOUND_ERR,
55+ STRING_MESSAGE_ARGUMENT, "name", pos->name,
56+ MESSAGE_ARGUMENT_END);
57+ }
58+ new_ref = MEM_malloc(sizeof(GlobalVariableRef));
59+ new_ref->variable = variable;
60+ new_ref->next = env->global_variable;
61+ env->global_variable = new_ref;
62+ NEXT_IDENTIFIER:
63+ ;
64+ }
65+
66+ return result;
67+}
68+
69+static StatementResult
70+execute_elsif(CRB_Interpreter *inter, LocalEnvironment *env,
71+ Elsif *elsif_list, CRB_Boolean *executed)
72+{
73+ StatementResult result;
74+ CRB_Value cond;
75+ Elsif *pos;
76+
77+ *executed = CRB_FALSE;
78+ result.type = NORMAL_STATEMENT_RESULT;
79+ for (pos = elsif_list; pos; pos = pos->next) {
80+ cond = crb_eval_expression(inter, env, pos->condition);
81+ if (cond.type != CRB_BOOLEAN_VALUE) {
82+ crb_runtime_error(pos->condition->line_number,
83+ NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
84+ }
85+ if (cond.u.boolean_value) {
86+ result = crb_execute_statement_list(inter, env,
87+ pos->block->statement_list);
88+ *executed = CRB_TRUE;
89+ if (result.type != NORMAL_STATEMENT_RESULT)
90+ goto FUNC_END;
91+ }
92+ }
93+
94+ FUNC_END:
95+ return result;
96+}
97+
98+static StatementResult
99+execute_if_statement(CRB_Interpreter *inter, LocalEnvironment *env,
100+ Statement *statement)
101+{
102+ StatementResult result;
103+ CRB_Value cond;
104+
105+ result.type = NORMAL_STATEMENT_RESULT;
106+ cond = crb_eval_expression(inter, env, statement->u.if_s.condition);
107+ if (cond.type != CRB_BOOLEAN_VALUE) {
108+ crb_runtime_error(statement->u.if_s.condition->line_number,
109+ NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
110+ }
111+ DBG_assert(cond.type == CRB_BOOLEAN_VALUE, ("cond.type..%d", cond.type));
112+
113+ if (cond.u.boolean_value) {
114+ result = crb_execute_statement_list(inter, env,
115+ statement->u.if_s.then_block
116+ ->statement_list);
117+ } else {
118+ CRB_Boolean elsif_executed;
119+ result = execute_elsif(inter, env, statement->u.if_s.elsif_list,
120+ &elsif_executed);
121+ if (result.type != NORMAL_STATEMENT_RESULT)
122+ goto FUNC_END;
123+ if (!elsif_executed && statement->u.if_s.else_block) {
124+ result = crb_execute_statement_list(inter, env,
125+ statement->u.if_s.else_block
126+ ->statement_list);
127+ }
128+ }
129+
130+ FUNC_END:
131+ return result;
132+}
133+
134+static StatementResult
135+execute_while_statement(CRB_Interpreter *inter, LocalEnvironment *env,
136+ Statement *statement)
137+{
138+ StatementResult result;
139+ CRB_Value cond;
140+
141+ result.type = NORMAL_STATEMENT_RESULT;
142+ for (;;) {
143+ cond = crb_eval_expression(inter, env, statement->u.while_s.condition);
144+ if (cond.type != CRB_BOOLEAN_VALUE) {
145+ crb_runtime_error(statement->u.while_s.condition->line_number,
146+ NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
147+ }
148+ DBG_assert(cond.type == CRB_BOOLEAN_VALUE,
149+ ("cond.type..%d", cond.type));
150+ if (!cond.u.boolean_value)
151+ break;
152+
153+ result = crb_execute_statement_list(inter, env,
154+ statement->u.while_s.block
155+ ->statement_list);
156+ if (result.type == RETURN_STATEMENT_RESULT) {
157+ break;
158+ } else if (result.type == BREAK_STATEMENT_RESULT) {
159+ result.type = NORMAL_STATEMENT_RESULT;
160+ break;
161+ }
162+ }
163+
164+ return result;
165+}
166+
167+static StatementResult
168+execute_for_statement(CRB_Interpreter *inter, LocalEnvironment *env,
169+ Statement *statement)
170+{
171+ StatementResult result;
172+ CRB_Value cond;
173+
174+ result.type = NORMAL_STATEMENT_RESULT;
175+
176+ if (statement->u.for_s.init) {
177+ crb_eval_expression(inter, env, statement->u.for_s.init);
178+ }
179+ for (;;) {
180+ if (statement->u.for_s.condition) {
181+ cond = crb_eval_expression(inter, env,
182+ statement->u.for_s.condition);
183+ if (cond.type != CRB_BOOLEAN_VALUE) {
184+ crb_runtime_error(statement->u.for_s.condition->line_number,
185+ NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
186+ }
187+ DBG_assert(cond.type == CRB_BOOLEAN_VALUE,
188+ ("cond.type..%d", cond.type));
189+ if (!cond.u.boolean_value)
190+ break;
191+ }
192+ result = crb_execute_statement_list(inter, env,
193+ statement->u.for_s.block
194+ ->statement_list);
195+ if (result.type == RETURN_STATEMENT_RESULT) {
196+ break;
197+ } else if (result.type == BREAK_STATEMENT_RESULT) {
198+ result.type = NORMAL_STATEMENT_RESULT;
199+ break;
200+ }
201+
202+ if (statement->u.for_s.post) {
203+ crb_eval_expression(inter, env, statement->u.for_s.post);
204+ }
205+ }
206+
207+ return result;
208+}
209+
210+static StatementResult
211+execute_return_statement(CRB_Interpreter *inter, LocalEnvironment *env,
212+ Statement *statement)
213+{
214+ StatementResult result;
215+
216+ result.type = RETURN_STATEMENT_RESULT;
217+ if (statement->u.return_s.return_value) {
218+ result.u.return_value
219+ = crb_eval_expression(inter, env,
220+ statement->u.return_s.return_value);
221+ } else {
222+ result.u.return_value.type = CRB_NULL_VALUE;
223+ }
224+
225+ return result;
226+}
227+
228+static StatementResult
229+execute_break_statement(CRB_Interpreter *inter, LocalEnvironment *env,
230+ Statement *statement)
231+{
232+ StatementResult result;
233+
234+ result.type = BREAK_STATEMENT_RESULT;
235+
236+ return result;
237+}
238+
239+static StatementResult
240+execute_continue_statement(CRB_Interpreter *inter, LocalEnvironment *env,
241+ Statement *statement)
242+{
243+ StatementResult result;
244+
245+ result.type = CONTINUE_STATEMENT_RESULT;
246+
247+ return result;
248+}
249+
250+static StatementResult
251+execute_statement(CRB_Interpreter *inter, LocalEnvironment *env,
252+ Statement *statement)
253+{
254+ StatementResult result;
255+
256+ result.type = NORMAL_STATEMENT_RESULT;
257+
258+ switch (statement->type) {
259+ case EXPRESSION_STATEMENT:
260+ result = execute_expression_statement(inter, env, statement);
261+ break;
262+ case GLOBAL_STATEMENT:
263+ result = execute_global_statement(inter, env, statement);
264+ break;
265+ case IF_STATEMENT:
266+ result = execute_if_statement(inter, env, statement);
267+ break;
268+ case WHILE_STATEMENT:
269+ result = execute_while_statement(inter, env, statement);
270+ break;
271+ case FOR_STATEMENT:
272+ result = execute_for_statement(inter, env, statement);
273+ break;
274+ case RETURN_STATEMENT:
275+ result = execute_return_statement(inter, env, statement);
276+ break;
277+ case BREAK_STATEMENT:
278+ result = execute_break_statement(inter, env, statement);
279+ break;
280+ case CONTINUE_STATEMENT:
281+ result = execute_continue_statement(inter, env, statement);
282+ break;
283+ case STATEMENT_TYPE_COUNT_PLUS_1: /* FALLTHRU */
284+ default:
285+ DBG_panic(("bad case...%d", statement->type));
286+ }
287+
288+ return result;
289+}
290+
291+StatementResult
292+crb_execute_statement_list(CRB_Interpreter *inter, LocalEnvironment *env,
293+ StatementList *list)
294+{
295+ StatementList *pos;
296+ StatementResult result;
297+
298+ result.type = NORMAL_STATEMENT_RESULT;
299+ for (pos = list; pos; pos = pos->next) {
300+ result = execute_statement(inter, env, pos->statement);
301+ if (result.type != NORMAL_STATEMENT_RESULT)
302+ goto FUNC_END;
303+ }
304+
305+ FUNC_END:
306+ return result;
307+}
--- trunk/crowbar/ver0.1/interface.c (nonexistent)
+++ trunk/crowbar/ver0.1/interface.c (revision 31)
@@ -0,0 +1,99 @@
1+#include "MEM.h"
2+#include "DBG.h"
3+#define GLOBAL_VARIABLE_DEFINE
4+#include "crowbar.h"
5+
6+static void
7+add_native_functions(CRB_Interpreter *inter)
8+{
9+ CRB_add_native_function(inter, "print", crb_nv_print_proc);
10+ CRB_add_native_function(inter, "fopen", crb_nv_fopen_proc);
11+ CRB_add_native_function(inter, "fclose", crb_nv_fclose_proc);
12+ CRB_add_native_function(inter, "fgets", crb_nv_fgets_proc);
13+ CRB_add_native_function(inter, "fputs", crb_nv_fputs_proc);
14+}
15+
16+CRB_Interpreter *
17+CRB_create_interpreter(void)
18+{
19+ MEM_Storage storage;
20+ CRB_Interpreter *interpreter;
21+
22+ storage = MEM_open_storage(0);
23+ interpreter = MEM_storage_malloc(storage,
24+ sizeof(struct CRB_Interpreter_tag));
25+ interpreter->interpreter_storage = storage;
26+ interpreter->execute_storage = NULL;
27+ interpreter->variable = NULL;
28+ interpreter->function_list = NULL;
29+ interpreter->statement_list = NULL;
30+ interpreter->current_line_number = 1;
31+
32+ crb_set_current_interpreter(interpreter);
33+ add_native_functions(interpreter);
34+
35+ return interpreter;
36+}
37+
38+void
39+CRB_compile(CRB_Interpreter *interpreter, FILE *fp)
40+{
41+ extern int yyparse(void);
42+ extern FILE *yyin;
43+
44+ crb_set_current_interpreter(interpreter);
45+
46+ yyin = fp;
47+ if (yyparse()) {
48+ /* BUGBUG */
49+ fprintf(stderr, "Error ! Error ! Error !\n");
50+ exit(1);
51+ }
52+ crb_reset_string_literal_buffer();
53+}
54+
55+void
56+CRB_interpret(CRB_Interpreter *interpreter)
57+{
58+ interpreter->execute_storage = MEM_open_storage(0);
59+ crb_add_std_fp(interpreter);
60+ crb_execute_statement_list(interpreter, NULL, interpreter->statement_list);
61+}
62+
63+static void
64+release_global_strings(CRB_Interpreter *interpreter) {
65+ while (interpreter->variable) {
66+ Variable *temp = interpreter->variable;
67+ interpreter->variable = temp->next;
68+ if (temp->value.type == CRB_STRING_VALUE) {
69+ crb_release_string(temp->value.u.string_value);
70+ }
71+ }
72+}
73+
74+void
75+CRB_dispose_interpreter(CRB_Interpreter *interpreter)
76+{
77+ release_global_strings(interpreter);
78+
79+ if (interpreter->execute_storage) {
80+ MEM_dispose_storage(interpreter->execute_storage);
81+ }
82+
83+ MEM_dispose_storage(interpreter->interpreter_storage);
84+}
85+
86+void
87+CRB_add_native_function(CRB_Interpreter *interpreter,
88+ char *name, CRB_NativeFunctionProc *proc)
89+{
90+ FunctionDefinition *fd;
91+
92+ fd = crb_malloc(sizeof(FunctionDefinition));
93+ fd->name = name;
94+ fd->type = NATIVE_FUNCTION_DEFINITION;
95+ fd->u.native_f.proc = proc;
96+ fd->next = interpreter->function_list;
97+
98+ interpreter->function_list = fd;
99+}
--- trunk/crowbar/ver0.1/main.c (nonexistent)
+++ trunk/crowbar/ver0.1/main.c (revision 31)
@@ -0,0 +1,29 @@
1+#include <stdio.h>
2+#include "CRB.h"
3+#include "MEM.h"
4+
5+int
6+main(int argc, char **argv)
7+{
8+ CRB_Interpreter *interpreter;
9+ FILE *fp;
10+
11+ if (argc != 2) {
12+ fprintf(stderr, "usage:%s filename", argv[0]);
13+ exit(1);
14+ }
15+
16+ fp = fopen(argv[1], "r");
17+ if (fp == NULL) {
18+ fprintf(stderr, "%s not found.\n", argv[1]);
19+ exit(1);
20+ }
21+ interpreter = CRB_create_interpreter();
22+ CRB_compile(interpreter, fp);
23+ CRB_interpret(interpreter);
24+ CRB_dispose_interpreter(interpreter);
25+
26+ MEM_dump_blocks(stdout);
27+
28+ return 0;
29+}
--- trunk/crowbar/ver0.1/memory/Makefile (nonexistent)
+++ trunk/crowbar/ver0.1/memory/Makefile (revision 31)
@@ -0,0 +1,13 @@
1+TARGET = mem.o
2+CFLAGS = -c -g -DDEBUG -Wall -ansi -pedantic
3+OBJS = memory.o storage.o
4+
5+$(TARGET):$(OBJS)
6+ ld -r -o $@ $(OBJS)
7+testp : $(OBJS) main.o
8+ $(CC) -o $@ $(OBJS) main.o
9+.c.o:
10+ $(CC) $(CFLAGS) -I.. $*.c
11+main.o: main.c ../MEM.h
12+memory.o: memory.c memory.h ../MEM.h
13+storage.o: storage.c memory.h ../MEM.h
--- trunk/crowbar/ver0.1/memory/main.c (nonexistent)
+++ trunk/crowbar/ver0.1/memory/main.c (revision 31)
@@ -0,0 +1,68 @@
1+#include "MEM.h"
2+
3+static void
4+dump_buffer(unsigned char *buf, int size)
5+{
6+ int i;
7+
8+ for (i = 0; i < size; i++) {
9+ printf("%02x ", buf[i]);
10+ if (i % 16 == 15) {
11+ printf("\n");
12+ }
13+ }
14+ printf("\n");
15+}
16+
17+static void
18+fill_buffer(unsigned char *buf, int size)
19+{
20+ int i;
21+
22+ for (i = 0; i < size; i++) {
23+ buf[i] = i;
24+ }
25+}
26+
27+int
28+main(void)
29+{
30+ unsigned char *p1;
31+ unsigned char *p2;
32+ unsigned char *p3;
33+
34+ p1 = MEM_malloc(10);
35+ dump_buffer(p1, 10);
36+ fill_buffer(p1, 10);
37+ dump_buffer(p1, 10);
38+
39+ MEM_dump_blocks(stdout);
40+
41+ p2 = MEM_malloc(10);
42+ p2 = MEM_realloc(p2, 15);
43+ dump_buffer(p2, 15);
44+ MEM_dump_blocks(stdout);
45+
46+ p2 = MEM_realloc(p2, 8);
47+ dump_buffer(p2, 8);
48+ MEM_dump_blocks(stdout);
49+
50+ p3 = NULL;
51+ p3 = MEM_realloc(p3, 10);
52+ dump_buffer(p3, 10);
53+ fill_buffer(p3, 10);
54+ dump_buffer(p3, 10);
55+ MEM_dump_blocks(stdout);
56+
57+ MEM_free(p2);
58+ dump_buffer(p2, 8);
59+ MEM_free(p1);
60+ dump_buffer(p1, 10);
61+ MEM_free(p3);
62+ dump_buffer(p3, 10);
63+ fprintf(stderr, "final dump\n");
64+ MEM_dump_blocks(stdout);
65+
66+ return 0;
67+}
68+
--- trunk/crowbar/ver0.1/memory/memory.c (nonexistent)
+++ trunk/crowbar/ver0.1/memory/memory.c (revision 31)
@@ -0,0 +1,344 @@
1+#include <stdio.h>
2+#include <stdlib.h>
3+#include <string.h>
4+#include "memory.h"
5+
6+static void default_error_handler(MEM_Controller controller,
7+ char *filename, int line, char *msg);
8+
9+static struct MEM_Controller_tag st_default_controller = {
10+ NULL,/* stderr */
11+ default_error_handler,
12+ MEM_FAIL_AND_EXIT
13+};
14+MEM_Controller mem_default_controller = &st_default_controller;
15+
16+typedef union {
17+ long l_dummy;
18+ double d_dummy;
19+ void *p_dummy;
20+} Align;
21+
22+#define MARK_SIZE (4)
23+
24+typedef struct {
25+ int size;
26+ char *filename;
27+ int line;
28+ Header *prev;
29+ Header *next;
30+ unsigned char mark[MARK_SIZE];
31+} HeaderStruct;
32+
33+#define ALIGN_SIZE (sizeof(Align))
34+#define revalue_up_align(val) ((val) ? (((val) - 1) / ALIGN_SIZE + 1) : 0)
35+#define HEADER_ALIGN_SIZE (revalue_up_align(sizeof(HeaderStruct)))
36+#define MARK (0xCD)
37+
38+union Header_tag {
39+ HeaderStruct s;
40+ Align u[HEADER_ALIGN_SIZE];
41+};
42+
43+static void
44+default_error_handler(MEM_Controller controller,
45+ char *filename, int line, char *msg)
46+{
47+ fprintf(controller->error_fp,
48+ "MEM:%s failed in %s at %d\n", msg, filename, line);
49+}
50+
51+static void
52+error_handler(MEM_Controller controller, char *filename, int line, char *msg)
53+{
54+ if (controller->error_fp == NULL) {
55+ controller->error_fp = stderr;
56+ }
57+ controller->error_handler(controller, filename, line, msg);
58+
59+ if (controller->fail_mode == MEM_FAIL_AND_EXIT) {
60+ exit(1);
61+ }
62+}
63+
64+MEM_Controller
65+MEM_create_controller(void)
66+{
67+ MEM_Controller p;
68+
69+ p = MEM_malloc_func(&st_default_controller, __FILE__, __LINE__,
70+ sizeof(struct MEM_Controller_tag));
71+ *p = st_default_controller;
72+
73+ return p;
74+}
75+
76+#ifdef DEBUG
77+static void
78+chain_block(MEM_Controller controller, Header *new_header)
79+{
80+ if (controller->block_header) {
81+ controller->block_header->s.prev = new_header;
82+ }
83+ new_header->s.prev = NULL;
84+ new_header->s.next = controller->block_header;
85+ controller->block_header = new_header;
86+}
87+
88+static void
89+rechain_block(MEM_Controller controller, Header *header)
90+{
91+ if (header->s.prev) {
92+ header->s.prev->s.next = header;
93+ } else {
94+ controller->block_header = header;
95+ }
96+ if (header->s.next) {
97+ header->s.next->s.prev = header;
98+ }
99+}
100+
101+static void
102+unchain_block(MEM_Controller controller, Header *header)
103+{
104+ if (header->s.prev) {
105+ header->s.prev->s.next = header->s.next;
106+ } else {
107+ controller->block_header = header->s.next;
108+ }
109+ if (header->s.next) {
110+ header->s.next->s.prev = header->s.prev;
111+ }
112+}
113+
114+void
115+set_header(Header *header, int size, char *filename, int line)
116+{
117+ header->s.size = size;
118+ header->s.filename = filename;
119+ header->s.line = line;
120+ memset(header->s.mark, MARK, (char*)&header[1] - (char*)header->s.mark);
121+}
122+
123+void
124+set_tail(void *ptr, int alloc_size)
125+{
126+ char *tail;
127+ tail = ((char*)ptr) + alloc_size - MARK_SIZE;
128+ memset(tail, MARK, MARK_SIZE);
129+}
130+
131+void
132+check_mark_sub(unsigned char *mark, int size)
133+{
134+ int i;
135+
136+ for (i = 0; i < size; i++) {
137+ if (mark[i] != MARK) {
138+ fprintf(stderr, "bad mark\n");
139+ abort();
140+ }
141+ }
142+}
143+
144+void
145+check_mark(Header *header)
146+{
147+ unsigned char *tail;
148+ check_mark_sub(header->s.mark, (char*)&header[1] - (char*)header->s.mark);
149+ tail = ((unsigned char*)header) + header->s.size + sizeof(Header);
150+ check_mark_sub(tail, MARK_SIZE);
151+}
152+#endif /* DEBUG */
153+
154+void*
155+MEM_malloc_func(MEM_Controller controller, char *filename, int line,
156+ size_t size)
157+{
158+ void *ptr;
159+ size_t alloc_size;
160+
161+#ifdef DEBUG
162+ alloc_size = size + sizeof(Header) + MARK_SIZE;
163+#else
164+ alloc_size = size;
165+#endif
166+ ptr = malloc(alloc_size);
167+ if (ptr == NULL) {
168+ error_handler(controller, filename, line, "malloc");
169+ }
170+
171+#ifdef DEBUG
172+ memset(ptr, 0xCC, alloc_size);
173+ set_header(ptr, size, filename, line);
174+ set_tail(ptr, alloc_size);
175+ chain_block(controller, (Header*)ptr);
176+ ptr = (char*)ptr + sizeof(Header);
177+#endif
178+
179+ return ptr;
180+}
181+
182+void*
183+MEM_realloc_func(MEM_Controller controller, char *filename, int line,
184+ void *ptr, size_t size)
185+{
186+ void *new_ptr;
187+ size_t alloc_size;
188+ void *real_ptr;
189+#ifdef DEBUG
190+ Header old_header;
191+ int old_size;
192+
193+ alloc_size = size + sizeof(Header) + MARK_SIZE;
194+ if (ptr != NULL) {
195+ real_ptr = (char*)ptr - sizeof(Header);
196+ check_mark((Header*)real_ptr);
197+ old_header = *((Header*)real_ptr);
198+ old_size = old_header.s.size;
199+ unchain_block(controller, real_ptr);
200+ } else {
201+ real_ptr = NULL;
202+ old_size = 0;
203+ }
204+#else
205+ alloc_size = size;
206+ real_ptr = ptr;
207+#endif
208+
209+ new_ptr = realloc(real_ptr, alloc_size);
210+ if (new_ptr == NULL) {
211+ if (ptr == NULL) {
212+ error_handler(controller, filename, line, "realloc(malloc)");
213+ } else {
214+ error_handler(controller, filename, line, "realloc");
215+ free(real_ptr);
216+ }
217+ }
218+
219+#ifdef DEBUG
220+ if (ptr) {
221+ *((Header*)new_ptr) = old_header;
222+ ((Header*)new_ptr)->s.size = size;
223+ rechain_block(controller, (Header*)new_ptr);
224+ set_tail(new_ptr, alloc_size);
225+ } else {
226+ set_header(new_ptr, size, filename, line);
227+ set_tail(new_ptr, alloc_size);
228+ chain_block(controller, (Header*)new_ptr);
229+ }
230+ new_ptr = (char*)new_ptr + sizeof(Header);
231+ if (size > old_size) {
232+ memset((char*)new_ptr + old_size, 0xCC, size - old_size);
233+ }
234+#endif
235+
236+ return(new_ptr);
237+}
238+
239+char *
240+MEM_strdup_func(MEM_Controller controller, char *filename, int line,
241+ char *str)
242+{
243+ char *ptr;
244+ int size;
245+ size_t alloc_size;
246+
247+ size = strlen(str) + 1;
248+#ifdef DEBUG
249+ alloc_size = size + sizeof(Header) + MARK_SIZE;
250+#else
251+ alloc_size = size;
252+#endif
253+ ptr = malloc(alloc_size);
254+ if (ptr == NULL) {
255+ error_handler(controller, filename, line, "strdup");
256+ }
257+
258+#ifdef DEBUG
259+ memset(ptr, 0xCC, alloc_size);
260+ set_header((Header*)ptr, size, filename, line);
261+ set_tail(ptr, alloc_size);
262+ chain_block(controller, (Header*)ptr);
263+ ptr = (char*)ptr + sizeof(Header);
264+#endif
265+ strcpy(ptr, str);
266+
267+ return(ptr);
268+}
269+
270+void
271+MEM_free_func(MEM_Controller controller, void *ptr)
272+{
273+ void *real_ptr;
274+#ifdef DEBUG
275+ int size;
276+#endif
277+ if (ptr == NULL)
278+ return;
279+
280+#ifdef DEBUG
281+ real_ptr = (char*)ptr - sizeof(Header);
282+ check_mark((Header*)real_ptr);
283+ size = ((Header*)real_ptr)->s.size;
284+ unchain_block(controller, real_ptr);
285+ memset(real_ptr, 0xCC, size + sizeof(Header));
286+#else
287+ real_ptr = ptr;
288+#endif
289+
290+ free(real_ptr);
291+}
292+
293+void
294+MEM_set_error_handler(MEM_Controller controller, MEM_ErrorHandler handler)
295+{
296+ controller->error_handler = handler;
297+}
298+
299+void
300+MEM_set_fail_mode(MEM_Controller controller, MEM_FailMode mode)
301+{
302+ controller->fail_mode = mode;
303+}
304+
305+void
306+MEM_dump_blocks_func(MEM_Controller controller, FILE *fp)
307+{
308+#ifdef DEBUG
309+ Header *pos;
310+ int counter = 0;
311+
312+ for (pos = controller->block_header; pos; pos = pos->s.next) {
313+ check_mark(pos);
314+ fprintf(fp, "[%04d]%p********************\n", counter,
315+ (char*)pos + sizeof(Header));
316+ fprintf(fp, "%s line %d size..%d\n",
317+ pos->s.filename, pos->s.line, pos->s.size);
318+ counter++;
319+ }
320+#endif /* DEBUG */
321+}
322+
323+void
324+MEM_check_block_func(MEM_Controller controller, char *filename, int line,
325+ void *p)
326+{
327+#ifdef DEBUG
328+ void *real_ptr = ((char*)p) - sizeof(Header);
329+
330+ check_mark(real_ptr);
331+#endif /* DEBUG */
332+}
333+
334+void MEM_check_all_blocks_func(MEM_Controller controller,
335+ char *filename, int line)
336+{
337+#ifdef DEBUG
338+ Header *pos;
339+
340+ for (pos = controller->block_header; pos; pos = pos->s.next) {
341+ check_mark(pos);
342+ }
343+#endif /* DEBUG */
344+}
--- trunk/crowbar/ver0.1/memory/memory.h (nonexistent)
+++ trunk/crowbar/ver0.1/memory/memory.h (revision 31)
@@ -0,0 +1,15 @@
1+#ifndef PRIVATE_MEM_H_INCLUDED
2+#define PRIVATE_MEM_H_INCLUDED
3+#include "MEM.h"
4+
5+typedef union Header_tag Header;
6+
7+
8+struct MEM_Controller_tag {
9+ FILE *error_fp;
10+ MEM_ErrorHandler error_handler;
11+ MEM_FailMode fail_mode;
12+ Header *block_header;
13+};
14+#endif /* PRIVATE_MEM_H_INCLUDED */
15+
--- trunk/crowbar/ver0.1/memory/storage.c (nonexistent)
+++ trunk/crowbar/ver0.1/memory/storage.c (revision 31)
@@ -0,0 +1,97 @@
1+#include <stdio.h>
2+#include <stdlib.h>
3+#include <assert.h>
4+#include "memory.h"
5+
6+typedef union {
7+ long l_dummy;
8+ double d_dummy;
9+ void *p_dummy;
10+} Cell;
11+
12+#define CELL_SIZE (sizeof(Cell))
13+#define DEFAULT_PAGE_SIZE (1024) /* cell num */
14+
15+typedef struct MemoryPage_tag MemoryPage;
16+typedef MemoryPage *MemoryPageList;
17+
18+struct MemoryPage_tag {
19+ int cell_num;
20+ int use_cell_num;
21+ MemoryPageList next;
22+ Cell cell[1];
23+};
24+
25+struct MEM_Storage_tag {
26+ MemoryPageList page_list;
27+ int current_page_size;
28+};
29+
30+#define larger(a, b) (((a) > (b)) ? (a) : (b))
31+
32+MEM_Storage
33+MEM_open_storage_func(MEM_Controller controller,
34+ char *filename, int line, int page_size)
35+{
36+ MEM_Storage storage;
37+
38+ storage = MEM_malloc_func(controller, filename, line,
39+ sizeof(struct MEM_Storage_tag));
40+ storage->page_list = NULL;
41+ assert(page_size >= 0);
42+ if (page_size > 0) {
43+ storage->current_page_size = page_size;
44+ } else {
45+ storage->current_page_size = DEFAULT_PAGE_SIZE;
46+ }
47+
48+ return storage;
49+}
50+
51+void*
52+MEM_storage_malloc_func(MEM_Controller controller,
53+ char *filename, int line, MEM_Storage storage,
54+ size_t size)
55+{
56+ int cell_num;
57+ MemoryPage *new_page;
58+ void *p;
59+
60+ cell_num = ((size - 1) / CELL_SIZE) + 1;
61+
62+ if (storage->page_list != NULL
63+ && (storage->page_list->use_cell_num + cell_num
64+ < storage->page_list->cell_num)) {
65+ p = &(storage->page_list->cell[storage->page_list->use_cell_num]);
66+ storage->page_list->use_cell_num += cell_num;
67+ } else {
68+ int alloc_cell_num;
69+
70+ alloc_cell_num = larger(cell_num, storage->current_page_size);
71+
72+ new_page = MEM_malloc_func(controller, filename, line,
73+ sizeof(MemoryPage)
74+ + CELL_SIZE * (alloc_cell_num - 1));
75+ new_page->next = storage->page_list;
76+ new_page->cell_num = alloc_cell_num;
77+ storage->page_list = new_page;
78+
79+ p = &(new_page->cell[0]);
80+ new_page->use_cell_num = cell_num;
81+ }
82+
83+ return p;
84+}
85+
86+void
87+MEM_dispose_storage_func(MEM_Controller controller, MEM_Storage storage)
88+{
89+ MemoryPage *temp;
90+
91+ while (storage->page_list) {
92+ temp = storage->page_list->next;
93+ MEM_free_func(controller, storage->page_list);
94+ storage->page_list = temp;
95+ }
96+ MEM_free_func(controller, storage);
97+}
--- trunk/crowbar/ver0.1/native.c (nonexistent)
+++ trunk/crowbar/ver0.1/native.c (revision 31)
@@ -0,0 +1,210 @@
1+#include <stdio.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "DBG.h"
5+#include "CRB_dev.h"
6+#include "crowbar.h"
7+
8+#define NATIVE_LIB_NAME "crowbar.lang.file"
9+
10+static CRB_NativePointerInfo st_native_lib_info = {
11+ NATIVE_LIB_NAME
12+};
13+
14+CRB_Value crb_nv_print_proc(CRB_Interpreter *interpreter,
15+ int arg_count, CRB_Value *args)
16+{
17+ CRB_Value value;
18+
19+ value.type = CRB_NULL_VALUE;
20+
21+ if (arg_count < 1) {
22+ crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
23+ MESSAGE_ARGUMENT_END);
24+ } else if (arg_count > 1) {
25+ crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
26+ MESSAGE_ARGUMENT_END);
27+ }
28+ switch (args[0].type) {
29+ case CRB_BOOLEAN_VALUE:
30+ if (args[0].u.boolean_value) {
31+ printf("true");
32+ } else {
33+ printf("false");
34+ }
35+ break;
36+ case CRB_INT_VALUE:
37+ printf("%d", args[0].u.int_value);
38+ break;
39+ case CRB_DOUBLE_VALUE:
40+ printf("%f", args[0].u.double_value);
41+ break;
42+ case CRB_STRING_VALUE:
43+ printf("%s", args[0].u.string_value->string);
44+ break;
45+ case CRB_NATIVE_POINTER_VALUE:
46+ printf("(%s:%p)",
47+ args[0].u.native_pointer.info->name,
48+ args[0].u.native_pointer.pointer);
49+ break;
50+ case CRB_NULL_VALUE:
51+ printf("null");
52+ break;
53+ }
54+
55+ return value;
56+}
57+
58+CRB_Value crb_nv_fopen_proc(CRB_Interpreter *interpreter,
59+ int arg_count, CRB_Value *args)
60+{
61+ CRB_Value value;
62+ FILE *fp;
63+
64+ if (arg_count < 2) {
65+ crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
66+ MESSAGE_ARGUMENT_END);
67+ } else if (arg_count > 2) {
68+ crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
69+ MESSAGE_ARGUMENT_END);
70+ }
71+ if (args[0].type != CRB_STRING_VALUE
72+ || args[1].type != CRB_STRING_VALUE) {
73+ crb_runtime_error(0, FOPEN_ARGUMENT_TYPE_ERR,
74+ MESSAGE_ARGUMENT_END);
75+ }
76+
77+ fp = fopen(args[0].u.string_value->string,
78+ args[1].u.string_value->string);
79+ if (fp == NULL) {
80+ value.type = CRB_NULL_VALUE;
81+ } else {
82+ value.type = CRB_NATIVE_POINTER_VALUE;
83+ value.u.native_pointer.info = &st_native_lib_info;
84+ value.u.native_pointer.pointer = fp;
85+ }
86+
87+ return value;
88+}
89+
90+static CRB_Boolean
91+check_native_pointer(CRB_Value *value)
92+{
93+ return value->u.native_pointer.info == &st_native_lib_info;
94+}
95+
96+CRB_Value crb_nv_fclose_proc(CRB_Interpreter *interpreter,
97+ int arg_count, CRB_Value *args)
98+{
99+ CRB_Value value;
100+ FILE *fp;
101+
102+ value.type = CRB_NULL_VALUE;
103+ if (arg_count < 1) {
104+ crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
105+ MESSAGE_ARGUMENT_END);
106+ } else if (arg_count > 1) {
107+ crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
108+ MESSAGE_ARGUMENT_END);
109+ }
110+ if (args[0].type != CRB_NATIVE_POINTER_VALUE
111+ || !check_native_pointer(&args[0])) {
112+ crb_runtime_error(0, FCLOSE_ARGUMENT_TYPE_ERR,
113+ MESSAGE_ARGUMENT_END);
114+ }
115+ fp = args[0].u.native_pointer.pointer;
116+ fclose(fp);
117+
118+ return value;
119+}
120+
121+CRB_Value crb_nv_fgets_proc(CRB_Interpreter *interpreter,
122+ int arg_count, CRB_Value *args)
123+{
124+ CRB_Value value;
125+ FILE *fp;
126+ char buf[LINE_BUF_SIZE];
127+ char *ret_buf = NULL;
128+ int ret_len = 0;
129+
130+ if (arg_count < 1) {
131+ crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
132+ MESSAGE_ARGUMENT_END);
133+ } else if (arg_count > 1) {
134+ crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
135+ MESSAGE_ARGUMENT_END);
136+ }
137+ if (args[0].type != CRB_NATIVE_POINTER_VALUE
138+ || !check_native_pointer(&args[0])) {
139+ crb_runtime_error(0, FGETS_ARGUMENT_TYPE_ERR,
140+ MESSAGE_ARGUMENT_END);
141+ }
142+ fp = args[0].u.native_pointer.pointer;
143+
144+ while (fgets(buf, LINE_BUF_SIZE, fp)) {
145+ int new_len;
146+ new_len = ret_len + strlen(buf);
147+ ret_buf = MEM_realloc(ret_buf, new_len + 1);
148+ if (ret_len == 0) {
149+ strcpy(ret_buf, buf);
150+ } else {
151+ strcat(ret_buf, buf);
152+ }
153+ ret_len = new_len;
154+ if (ret_buf[ret_len-1] == '\n')
155+ break;
156+ }
157+ if (ret_len > 0) {
158+ value.type = CRB_STRING_VALUE;
159+ value.u.string_value = crb_create_crowbar_string(interpreter, ret_buf);
160+ } else {
161+ value.type = CRB_NULL_VALUE;
162+ }
163+
164+ return value;
165+}
166+
167+CRB_Value crb_nv_fputs_proc(CRB_Interpreter *interpreter,
168+ int arg_count, CRB_Value *args)
169+{
170+ CRB_Value value;
171+ FILE *fp;
172+
173+ value.type = CRB_NULL_VALUE;
174+ if (arg_count < 2) {
175+ crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
176+ MESSAGE_ARGUMENT_END);
177+ } else if (arg_count > 2) {
178+ crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
179+ MESSAGE_ARGUMENT_END);
180+ }
181+ if (args[0].type != CRB_STRING_VALUE
182+ || (args[1].type != CRB_NATIVE_POINTER_VALUE
183+ || !check_native_pointer(&args[1]))) {
184+ crb_runtime_error(0, FPUTS_ARGUMENT_TYPE_ERR,
185+ MESSAGE_ARGUMENT_END);
186+ }
187+ fp = args[1].u.native_pointer.pointer;
188+
189+ fputs(args[0].u.string_value->string, fp);
190+
191+ return value;
192+}
193+
194+void
195+crb_add_std_fp(CRB_Interpreter *inter)
196+{
197+ CRB_Value fp_value;
198+
199+ fp_value.type = CRB_NATIVE_POINTER_VALUE;
200+ fp_value.u.native_pointer.info = &st_native_lib_info;
201+
202+ fp_value.u.native_pointer.pointer = stdin;
203+ CRB_add_global_variable(inter, "STDIN", &fp_value);
204+
205+ fp_value.u.native_pointer.pointer = stdout;
206+ CRB_add_global_variable(inter, "STDOUT", &fp_value);
207+
208+ fp_value.u.native_pointer.pointer = stderr;
209+ CRB_add_global_variable(inter, "STDERR", &fp_value);
210+}
--- trunk/crowbar/ver0.1/string.c (nonexistent)
+++ trunk/crowbar/ver0.1/string.c (revision 31)
@@ -0,0 +1,64 @@
1+#include <stdio.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "crowbar.h"
5+
6+#define STRING_ALLOC_SIZE (256)
7+
8+static char *st_string_literal_buffer = NULL;
9+static int st_string_literal_buffer_size = 0;
10+static int st_string_literal_buffer_alloc_size = 0;
11+
12+void
13+crb_open_string_literal(void)
14+{
15+ st_string_literal_buffer_size = 0;
16+}
17+
18+void
19+crb_add_string_literal(int letter)
20+{
21+ if (st_string_literal_buffer_size == st_string_literal_buffer_alloc_size) {
22+ st_string_literal_buffer_alloc_size += STRING_ALLOC_SIZE;
23+ st_string_literal_buffer
24+ = MEM_realloc(st_string_literal_buffer,
25+ st_string_literal_buffer_alloc_size);
26+ }
27+ st_string_literal_buffer[st_string_literal_buffer_size] = letter;
28+ st_string_literal_buffer_size++;
29+}
30+
31+void
32+crb_reset_string_literal_buffer(void)
33+{
34+ MEM_free(st_string_literal_buffer);
35+ st_string_literal_buffer = NULL;
36+ st_string_literal_buffer_size = 0;
37+ st_string_literal_buffer_alloc_size = 0;
38+}
39+
40+char *
41+crb_close_string_literal(void)
42+{
43+ char *new_str;
44+
45+ new_str = crb_malloc(st_string_literal_buffer_size + 1);
46+
47+ memcpy(new_str, st_string_literal_buffer, st_string_literal_buffer_size);
48+ new_str[st_string_literal_buffer_size] = '\0';
49+
50+ return new_str;
51+}
52+
53+char *
54+crb_create_identifier(char *str)
55+{
56+ char *new_str;
57+
58+ new_str = crb_malloc(strlen(str) + 1);
59+
60+ strcpy(new_str, str);
61+
62+ return new_str;
63+}
64+
--- trunk/crowbar/ver0.1/string_pool.c (nonexistent)
+++ trunk/crowbar/ver0.1/string_pool.c (revision 31)
@@ -0,0 +1,59 @@
1+#include <stdio.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "DBG.h"
5+#include "crowbar.h"
6+
7+static CRB_String *
8+alloc_crb_string(CRB_Interpreter *inter, char *str, CRB_Boolean is_literal)
9+{
10+ CRB_String *ret;
11+
12+ ret = MEM_malloc(sizeof(CRB_String));
13+ ret->ref_count = 0;
14+ ret->is_literal = is_literal;
15+ ret->string = str;
16+
17+ return ret;
18+}
19+
20+CRB_String *
21+crb_literal_to_crb_string(CRB_Interpreter *inter, char *str)
22+{
23+ CRB_String *ret;
24+
25+ ret = alloc_crb_string(inter, str, CRB_TRUE);
26+ ret->ref_count = 1;
27+
28+ return ret;
29+}
30+
31+void
32+crb_refer_string(CRB_String *str)
33+{
34+ str->ref_count++;
35+}
36+
37+void
38+crb_release_string(CRB_String *str)
39+{
40+ str->ref_count--;
41+
42+ DBG_assert(str->ref_count >= 0, ("str->ref_count..%d\n",
43+ str->ref_count));
44+ if (str->ref_count == 0) {
45+ if (!str->is_literal) {
46+ MEM_free(str->string);
47+ }
48+ MEM_free(str);
49+ }
50+}
51+
52+CRB_String *
53+crb_create_crowbar_string(CRB_Interpreter *inter, char *str)
54+{
55+ CRB_String *ret = alloc_crb_string(inter, str, CRB_FALSE);
56+ ret->ref_count = 1;
57+
58+ return ret;
59+}
--- trunk/crowbar/ver0.1/util.c (nonexistent)
+++ trunk/crowbar/ver0.1/util.c (revision 31)
@@ -0,0 +1,199 @@
1+#include <stdio.h>
2+#include <string.h>
3+#include "MEM.h"
4+#include "DBG.h"
5+#include "crowbar.h"
6+
7+static CRB_Interpreter *st_current_interpreter;
8+
9+CRB_Interpreter *
10+crb_get_current_interpreter(void)
11+{
12+ return st_current_interpreter;
13+}
14+
15+void
16+crb_set_current_interpreter(CRB_Interpreter *inter)
17+{
18+ st_current_interpreter = inter;
19+}
20+
21+/* BUGBUG
22+CRB_NativeFunctionProc *
23+crb_search_native_function(CRB_Interpreter *inter, char *name)
24+{
25+ NativeFunction *pos;
26+
27+ for (pos = inter->native_function; pos; pos = pos->next) {
28+ if (!strcmp(pos->name, name))
29+ break;
30+ }
31+ if (pos) {
32+ return pos->proc;
33+ } else {
34+ return NULL;
35+ }
36+}
37+*/
38+
39+FunctionDefinition *
40+crb_search_function(char *name)
41+{
42+ FunctionDefinition *pos;
43+ CRB_Interpreter *inter;
44+
45+ inter = crb_get_current_interpreter();
46+ for (pos = inter->function_list; pos; pos = pos->next) {
47+ if (!strcmp(pos->name, name))
48+ break;
49+ }
50+ return pos;
51+}
52+
53+void *
54+crb_malloc(size_t size)
55+{
56+ void *p;
57+ CRB_Interpreter *inter;
58+
59+ inter = crb_get_current_interpreter();
60+ p = MEM_storage_malloc(inter->interpreter_storage, size);
61+
62+ return p;
63+}
64+
65+void *
66+crb_execute_malloc(CRB_Interpreter *inter, size_t size)
67+{
68+ void *p;
69+
70+ p = MEM_storage_malloc(inter->execute_storage, size);
71+
72+ return p;
73+}
74+
75+Variable *
76+crb_search_local_variable(LocalEnvironment *env, char *identifier)
77+{
78+ Variable *pos;
79+
80+ if (env == NULL)
81+ return NULL;
82+ for (pos = env->variable; pos; pos = pos->next) {
83+ if (!strcmp(pos->name, identifier))
84+ break;
85+ }
86+ if (pos == NULL) {
87+ return NULL;
88+ } else {
89+ return pos;
90+ }
91+}
92+
93+Variable *
94+crb_search_global_variable(CRB_Interpreter *inter, char *identifier)
95+{
96+ Variable *pos;
97+
98+ for (pos = inter->variable; pos; pos = pos->next) {
99+ if (!strcmp(pos->name, identifier))
100+ return pos;
101+ }
102+
103+ return NULL;
104+}
105+
106+void
107+crb_add_local_variable(LocalEnvironment *env,
108+ char *identifier, CRB_Value *value)
109+{
110+ Variable *new_variable;
111+
112+ new_variable = MEM_malloc(sizeof(Variable));
113+ new_variable->name = identifier;
114+ new_variable->value = *value;
115+ new_variable->next = env->variable;
116+ env->variable = new_variable;
117+}
118+
119+void
120+CRB_add_global_variable(CRB_Interpreter *inter, char *identifier,
121+ CRB_Value *value)
122+{
123+ Variable *new_variable;
124+
125+ new_variable = crb_execute_malloc(inter, sizeof(Variable));
126+ new_variable->name = crb_execute_malloc(inter, strlen(identifier) + 1);
127+ strcpy(new_variable->name, identifier);
128+ new_variable->next = inter->variable;
129+ inter->variable = new_variable;
130+ new_variable->value = *value;
131+}
132+
133+char *
134+crb_get_operator_string(ExpressionType type)
135+{
136+ char *str;
137+
138+ switch (type) {
139+ case BOOLEAN_EXPRESSION: /* FALLTHRU */
140+ case INT_EXPRESSION: /* FALLTHRU */
141+ case DOUBLE_EXPRESSION: /* FALLTHRU */
142+ case STRING_EXPRESSION: /* FALLTHRU */
143+ case IDENTIFIER_EXPRESSION:
144+ DBG_panic(("bad expression type..%d\n", type));
145+ break;
146+ case ASSIGN_EXPRESSION:
147+ str = "=";
148+ break;
149+ case ADD_EXPRESSION:
150+ str = "+";
151+ break;
152+ case SUB_EXPRESSION:
153+ str = "-";
154+ break;
155+ case MUL_EXPRESSION:
156+ str = "*";
157+ break;
158+ case DIV_EXPRESSION:
159+ str = "/";
160+ break;
161+ case MOD_EXPRESSION:
162+ str = "%";
163+ break;
164+ case LOGICAL_AND_EXPRESSION:
165+ str = "&&";
166+ break;
167+ case LOGICAL_OR_EXPRESSION:
168+ str = "||";
169+ break;
170+ case EQ_EXPRESSION:
171+ str = "==";
172+ break;
173+ case NE_EXPRESSION:
174+ str = "!=";
175+ break;
176+ case GT_EXPRESSION:
177+ str = "<";
178+ break;
179+ case GE_EXPRESSION:
180+ str = "<=";
181+ break;
182+ case LT_EXPRESSION:
183+ str = ">";
184+ break;
185+ case LE_EXPRESSION:
186+ str = ">=";
187+ break;
188+ case MINUS_EXPRESSION:
189+ str = "-";
190+ break;
191+ case FUNCTION_CALL_EXPRESSION: /* FALLTHRU */
192+ case NULL_EXPRESSION: /* FALLTHRU */
193+ case EXPRESSION_TYPE_COUNT_PLUS_1:
194+ default:
195+ DBG_panic(("bad expression type..%d\n", type));
196+ }
197+
198+ return str;
199+}