root/src/rr_bin_eval.c

Revision 1eb94519d291051d1a07e4c29ecb03fc82fddc59, 7.7 kB (checked in by redbrain <redbrain@…>, 2 years ago)

re works for better safer garbage collection on pushing and poping contexts

  • Property mode set to 100644
Line 
1/**
2 * rr_bin_eval.c -> Part of Crules Programming language
3 *
4 * Crules is the legal property of its developers. Please refer to the
5 * COPYRIGHT file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21#ifdef HAVE_CONFIG_H
22# include "config.h"
23#else
24# define CMAKE 1
25# include "config.h.cmake"
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include <crules/crules.h>
33#include <crules/opcodes.h>
34#include <crules/symbols.h>
35#include <crules/objects.h>
36#include <crules/backend.h>
37#include <crules/runtime.h>
38#include <crules/garbage.h>
39#include <crules/operators.h>
40#include <crules/math.h>
41
42#define Crl_Lookup_Object_DEF( x,y,z )                  \
43  x = crl_rr_context_lookup_object_def( y, z );         \
44  if( !x ) {                                            \
45    crl_error("object <%s> not defined!\n", y );        \
46  }
47
48static crl_symbol_obj * item_assign( crl_symbol_obj *, crl_symbol_obj *,
49                                     crl_context_table * );
50
51crl_symbol_obj *
52crl_rr_literal_fold( crl_symbol_obj * lit, crl_context_table * context )
53{
54  crl_assert( lit->type == SYMBOL_PRIMARY );
55  crl_symbol_obj * retval = NULL;
56  crl_type_obj_def_t ** def = NULL;
57
58  switch( lit->op_a_t )
59    {
60    case TYPE_INTEGER:
61      Crl_Lookup_Object_DEF( def, "Int", &context );
62      break;
63
64    case TYPE_SYMBOL_NIL:
65      break;
66
67    default:
68      crl_fatal("invalid literal object <0x%x>!\n", lit->op_a_t );
69      break;
70    }
71
72  if( def )
73    {
74      void * s = ((*def)->init_hook( lit, def ));
75      Crl_Symbol_Init_Ctx( retval, context );
76
77      crl_obj_state_t * o = (crl_obj_state_t *)
78        crl_malloc( sizeof(crl_obj_state_t) );
79      o->identifier = crl_strdup( (*def)->identifier );
80      o->self = s;
81
82      o->context = NULL;
83
84      o->definition = def;
85
86      retval->exp = OP_EXPRESS;
87      retval->type = SYMBOL_PRIMARY;
88      retval->op_a_t = TYPE_OBJECT;
89      retval->op_a.object_state = o;
90    }
91
92  return retval;
93}
94
95static
96crl_symbol_obj * item_assign( crl_symbol_obj *opa, crl_symbol_obj *opb,
97                              crl_context_table *context )
98{
99  crl_assert( opb->type == SYMBOL_PRIMARY );
100  crl_symbol_obj * retval = NULL;
101
102  if( opb->op_a_t == TYPE_OBJECT )
103    {
104      if( !(crl_runtime_assignment( opa, opb, context)) )
105        {
106          crl_fatal("error inserting variable into table!\n");
107        }
108      retval = crl_runtime_evaluate_expression( opb, context );
109    }
110  else
111    {
112      crl_symbol_obj * val = crl_rr_literal_fold( opb, context );
113      if( !(crl_runtime_assignment( opa, val, context)) )
114        {
115          crl_fatal("error inserting variable into table!\n");
116        }
117      retval = crl_runtime_evaluate_expression( opb, context );
118    }
119
120  return retval;
121}
122
123/*==================================================================================*/
124
125crl_symbol_obj*
126crl_runtime_assign( crl_symbol_obj** op_a , crl_symbol_obj** op_b,
127                    crl_context_table * context )
128{
129  crl_symbol_obj *opa, *opb, *retval= NULL;
130  if( op_a && op_b ) { opa= *op_a; opb= *op_b; }
131  else {
132    crl_error("operands A or B are undefined!\n");
133    return NULL;
134  }
135
136  if( opa->type == SYMBOL_REFERENCE )
137    {
138      if( opb->type == SYMBOL_PRIMARY )
139        {
140          retval= item_assign( opa, opb, context );
141        }
142      else
143        {
144          crl_symbol_obj *t1= crl_runtime_expression_evaluator( opb, context );
145          if( t1 ) { retval= crl_runtime_assign( op_a, &t1, context ); }
146          else {
147            crl_fatal("symbol undefined error!\n");
148          }
149        }
150    }
151  else
152    {
153      crl_fatal("Invalid accessor for assignment <0x%x>!\n", opa->type );
154    }
155  return retval;
156}
157
158crl_symbol_obj *
159crl_runtime_obj_access( crl_symbol_obj * accessor, crl_symbol_obj * member,
160                        crl_context_table * context )
161{
162  crl_symbol_obj *retval = NULL;
163  crl_assert( accessor->op_a_t == TYPE_OBJECT );
164 
165  if( member->type == SYMBOL_REFERENCE )
166    {
167      crl_fatal("not implemented yet!\n");
168    }
169  else if( member->type == OP_CALL_GOTO )
170    {
171      struct crl_obj_state_t * o = accessor->op_a.object_state;
172      crl_context_table * m_ctx = (crl_context_table *)
173        crl_malloc( sizeof(crl_context_table) );
174      crl_rr_context_init_table( &m_ctx );
175
176      crl_rr_context_push( context->array[0], m_ctx );
177      crl_rr_context_push( o->context, m_ctx );
178
179      crl_symbol_obj** functor = crl_rr_context_lookup_function_def( member->op_a.string,
180                                                                     &m_ctx );
181      if( functor )
182        {
183          crl_debug("trying to call <%s:%s( ... )>!\n", o->identifier, member->op_a.string );
184          retval = crl_runtime_dispatch_function( member, functor, m_ctx, context );
185          crl_debug("finished call <%s:%s( ... )>!\n", o->identifier, member->op_a.string );
186
187          if( !retval )
188            {
189              Crl_Symbol_Init( retval );
190            }
191        }
192      else
193        {
194          crl_error("member function <%s> to accessor of type <%s> is not defined!\n",
195                    member->op_a.string, o->identifier );
196          retval = NULL;
197        }
198      crl_branch_context * cc1 = crl_rr_context_pop( m_ctx, false );
199      crl_branch_context * cc2 = crl_rr_context_pop( m_ctx, false );
200
201      if( cc1 != (o->context) )
202        {
203          crl_fatal("context stack corruption!\n");
204        }
205      if( cc2 != (context->array[0]) )
206        {
207          crl_fatal("context stack corruption!\n");
208        }
209    }
210  else
211    {
212      crl_fatal( "invalid semantic member type <0x%X>!\n",
213                 member->type );
214    }
215  return retval;
216}
217
218crl_symbol_obj *
219crl_runtime_access( crl_symbol_obj** op_a , crl_symbol_obj** op_b,
220                    crl_context_table * context )
221{
222  crl_symbol_obj *opa, *opb, *retval= NULL;
223  if( op_a && op_b ) { opa= *op_a; opb= *op_b; }
224  else {
225    crl_error("operands A or B are undefined!\n");
226    return NULL;
227  }
228
229  crl_symbol_obj * t1 = crl_runtime_evaluate_expression( opa, context );
230  crl_assert( t1->op_a_t == TYPE_OBJECT );
231
232  retval = crl_runtime_obj_access( t1, opb, context);
233
234  return retval;
235}
236
237crl_symbol_obj*
238crl_rr_binop_dispatch( crl_symbol_obj** op_a , crl_symbol_obj** op_b,
239                       crl_context_table * context, crl_opcode_t op )
240{
241  crl_symbol_obj *opa, *opb, *retval= NULL;
242  if( op_a && op_b ) { opa= *op_a; opb= *op_b; }
243  else {
244    crl_error("operands A or B are undefined!\n");
245    return NULL;
246  }
247
248  if( opa->type == SYMBOL_PRIMARY )
249    {
250      if( opb->type == SYMBOL_PRIMARY )
251        {
252          retval= crl_rr_math_dispatch( opa, opb, context, op );
253        }
254      else
255        {
256          crl_symbol_obj *t1= crl_runtime_expression_evaluator( opb, context );
257          if( t1 ) { retval= crl_rr_binop_dispatch( op_a, &t1, context, op ); }
258          else {
259            crl_fatal("symbol undefined error!\n");
260          }
261          t1->n_ref--;
262        }
263    }
264  else
265    {
266      if( opb->type == SYMBOL_PRIMARY )
267        {
268          crl_symbol_obj *t1= crl_runtime_expression_evaluator( opa, context );
269          if( t1 ) { retval= crl_rr_binop_dispatch( &t1, op_b, context, op ); }
270          else {
271            crl_fatal("symbol undefined error!\n");
272          }
273          t1->n_ref--;
274        }
275      else
276        {
277          crl_symbol_obj *t1, *t2;
278          t1= crl_runtime_expression_evaluator( opa, context );
279          if( t1 )
280            {
281              t2= crl_runtime_expression_evaluator( opb, context );
282              if( t2 ) { retval= crl_rr_binop_dispatch( &t1, &t2, context, op ); }
283              else {
284                crl_fatal("symbol undefined error!\n");
285              }
286            }
287          else {
288            crl_fatal("symbol undefined error!\n");
289          }
290          t1->n_ref--;
291          t2->n_ref--;
292        }
293    }
294
295  return retval;
296}
Note: See TracBrowser for help on using the browser.