Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
interpret.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  interpret.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
43 #include "noble.h"
44 
52 static n_int interpret_braces(n_individual_interpret * individual, n_byte * eval, n_int location)
53 {
54  n_int local_b_count;
55 
56  NA_ASSERT(individual, "individual NULL");
57  NA_ASSERT(eval, "eval NULL");
58 
59  local_b_count = individual->braces_count;
60  if(location == -1)
61  {
62  if(local_b_count == 0)
63  {
65  }
66  individual->braces_count--;
67  }
68  else
69  {
70  n_uint loop = 0;
71  n_byte *local_evaluate;
72  if(local_b_count == BRACES_MAX)
73  {
75  }
76  local_evaluate = individual->braces[ local_b_count ].evaluate;
77  while(loop < SIZE_OF_EVALUATE)
78  {
79  n_byte eval_val = 0;
80  if(eval != 0L)
81  {
82  eval_val = eval[loop];
83  }
84  local_evaluate[ loop++ ] = eval_val;
85  }
86  individual->braces[ local_b_count ].braces_start = location;
87  individual->braces_count++;
88  }
89  return 0;
90 }
91 
100 static n_int interpret_apply(n_interpret * code, n_individual_interpret * individual, n_byte * evaluate, n_int * number, n_byte end_char)
101 {
102  n_int val_a, val_b, val_c;
103 
104  NA_ASSERT(code, "code NULL");
105  NA_ASSERT(evaluate, "evaluate NULL");
106  NA_ASSERT(number, "number NULL");
107 
108  if (code == 0L) return SHOW_ERROR("No code provided");
109  if (evaluate == 0L) return SHOW_ERROR("Nothing to evaluate");
110  if (number == 0L) return SHOW_ERROR("No numbers provided");
111 
112  if(code->sc_output(code, individual, evaluate,&val_a) == -1)
113  {
115  }
116  if(evaluate[2] == end_char)
117  {
118  *number = val_a;
119  return 3;
120  }
121  if(evaluate[2] != APESCRIPT_OPERATOR)
122  {
124  }
125  if(code->sc_output(code, individual, &evaluate[4],&val_b) == -1)
126  {
128  }
129  val_c = val_a - val_b;
130  switch(evaluate[3])
131  {
132  case SYNTAX_MINUS:
133  *number = val_c;
134  break;
135  case SYNTAX_ADDITION:
136  *number = (val_a + val_b);
137  break;
138  case SYNTAX_MULTIPLY:
139  *number = (val_a * val_b);
140  break;
141  case SYNTAX_AND:
142  *number = (val_a & val_b);
143  break;
144  case SYNTAX_XOR:
145  *number = (val_a ^ val_b);
146  break;
147  case SYNTAX_OR:
148  *number = (val_a | val_b);
149  break;
150  case SYNTAX_GREATER_THAN:
151  *number = ((0 - val_c)<0);
152  break;
153  case SYNTAX_LESS_THAN:
154  *number = (val_c < 0);
155  break;
156  case SYNTAX_EQUAL_TO:
157  *number = (val_c == 0);
158  break;
159  case SYNTAX_NOT_EQUAL_TO:
160  *number = (val_c != 0);
161  break;
163  *number = (val_a && val_b);
164  break;
166  *number = (val_a || val_b);
167  break;
168  case SYNTAX_DIVISION:
169  if (val_b == 0)
170  *number = 0;
171  else
172  *number = (val_a / val_b);
173  break;
174  case SYNTAX_MODULUS:
175  if (val_b == 0)
176  *number = 0;
177  else
178  *number = (val_a % val_b);
179  break;
181  *number = ((0 - val_c) <= 0);
182  break;
183  case SYNTAX_LESS_EQUAL:
184  *number = (val_c <= 0);
185  break;
187  val_b = 0 - val_b;
189  if (val_b == 0)
190  {
191  *number = val_a;
192  }
193  else
194  {
195  if (val_b < 0)
196  {
197  *number = val_a << val_b;
198  }
199  else
200  {
201  val_b = 0 - val_b;
202  *number = val_a >> val_b;
203  }
204  }
205  break;
206  default:
208  break;
209  }
210 
211  if(evaluate[6] == end_char)
212  {
213  return 7;
214  }
215  return io_apescript_error(individual->interpret_data, AE_WRONG_END);
216 }
217 
225 static n_int interpret_syntax(n_interpret * code, n_individual_interpret * individual, n_byte * value, n_int location)
226 {
227  n_byte first_value;
228  n_byte second_value;
229  n_int output_number = 0;
230 
231  NA_ASSERT(code, "code NULL");
232  NA_ASSERT(value, "value NULL");
233 
234  if (code == 0L) return SHOW_ERROR("No code provided");
235  if (value == 0L) return SHOW_ERROR("No values provided");
236 
237  first_value = value[0];
238  second_value = value[1];
239 
240  if(first_value == APESCRIPT_CLOSE_BRACE) /* what do you do with the tailing brace? */
241  {
242  n_brace *local_brace;
243  n_int brace_value = (individual->braces_count) - 1;
244  if(brace_value < 0 )
245  {
247  }
248  local_brace = &(individual->braces[brace_value]);
249  if(local_brace->evaluate[0] == 0) /* exit if */
250  {
251  if(interpret_braces(individual, 0L, -1) == -1)
252  {
253  return -1; /* Enough error information provided by this point */
254  }
255  SC_DEBUG_STRING(individual->interpret_data, "}");
256  SC_DEBUG_DOWN(individual->interpret_data);
257  SC_DEBUG_NEWLINE(individual->interpret_data);
258  return 1;
259  }
260  return 0; /* exit while and run function */
261  }
262  if(first_value != APESCRIPT_TEXT)
263  {
265  }
266 
267  if((second_value > VARIABLE_IF) && (second_value <= code->input_greater))
268  {
270  }
271 
272  if(VARIABLE_SPECIAL(second_value,code)) /* if/while/function/run( something ){} */
273  {
274  n_int return_value;
275  n_int error_value = -1;
276  if(value[2] != APESCRIPT_OPEN_BRACKET)
277  {
279  }
280  return_value = interpret_apply(code, individual, &value[3], &output_number, APESCRIPT_CLOSE_BRACKET);
281  if(return_value == -1)
282  {
283  return -1; /* Enough information presented by this point */
284  }
285  if(second_value == VARIABLE_FUNCTION || second_value == VARIABLE_RUN)
286  {
287  if(value[3] != APESCRIPT_TEXT)
288  {
290  }
291  if(return_value != 3)
292  {
294  }
295  }
296  else
297  {
298  SC_DEBUG_STRING(individual->interpret_data, scdebug_variable(second_value));
299  SC_DEBUG_STRING(individual->interpret_data, " ( ) {");
300  if(output_number == 0)
301  {
302  SC_DEBUG_STRING(individual->interpret_data, " }");
303  }
304  else
305  {
306  SC_DEBUG_UP(individual->interpret_data);
307  }
308  SC_DEBUG_NEWLINE(individual->interpret_data);
309  }
310  if(second_value == VARIABLE_FUNCTION)
311  {
312  if(output_number != 0)
313  {
315  }
316  }
317  if(second_value == VARIABLE_RUN)
318  {
319  if((output_number < 1) || (output_number > 0xFFFF))
320  {
322  }
323  if(value[3 + return_value] != APESCRIPT_SEMICOLON)
324  {
326  }
327  {
328  n_byte function_location[SIZE_OF_EVALUATE] = {APESCRIPT_FUNCTION,0};
329  n_byte *location_write =(n_byte *)&function_location[1];
330  n_int continuation = return_value + 4 + location;
331  io_int_to_bytes(output_number, location_write);
332  location_write = (n_byte *)&function_location[1 + SIZEOF_NUMBER_WRITE];
333  io_int_to_bytes(continuation,location_write);
334  if(interpret_braces(individual, (n_byte *)function_location, 0) == -1)
335  {
336  return -1; /* Enough information presented by this point */
337  }
338  }
339  SC_DEBUG_STRING(individual->interpret_data,"run( ");
340  SC_DEBUG_STRING(individual->interpret_data,scdebug_variable(value[4]));
341  SC_DEBUG_STRING(individual->interpret_data," ){");
342  SC_DEBUG_UP(individual->interpret_data);
343  SC_DEBUG_NEWLINE(individual->interpret_data);
344  return 0; /* want to trigger while check */
345  }
346  /* if the future code will contain if()run(); then the if should be checked here */
347  if(value[3 + return_value] != APESCRIPT_OPEN_BRACE)
348  {
350  }
351  if(second_value == VARIABLE_FUNCTION)
352  {
353  if(code->sc_input(individual, value[4], (4 + return_value + location) ) == -1)
354  {
356  }
357  if(value[4] == code->main_entry)
358  {
359  if(interpret_braces(individual,0L,0) == -1)
360  {
362  }
363  individual->main_status = MAIN_RUN;
364  SC_DEBUG_STRING(individual->interpret_data, "function( ");
365  SC_DEBUG_STRING(individual->interpret_data, scdebug_variable(value[4]));
366  SC_DEBUG_STRING(individual->interpret_data, " ){");
367  SC_DEBUG_UP(individual->interpret_data);
368  SC_DEBUG_NEWLINE(individual->interpret_data);
369  return 3 + 4; /* tF(tf){*/
370  }
371  if(individual->main_status != MAIN_NOT_RUN)
372  {
374  }
375  }
376  /* if the result is zero find the end of the correctly nested } */
377  if(output_number == 0)
378  {
379  n_int loop = return_value + 4;
380  n_int braces_open = 1;
381  n_int remaining_bytes = code->binary_code->location;
382  do
383  {
384  n_byte actual_value = value[loop++];
385  /* get actual point, avoid text variable numerical reference to { } */
386  if(CODE_VALUE_REQUIRED(actual_value))
387  loop++;
388  if(actual_value == APESCRIPT_OPEN_BRACE)
389  {
390  braces_open ++;
391  }
392  if(actual_value == APESCRIPT_CLOSE_BRACE)
393  {
394  braces_open --;
395  }
396  if((loop + location) > remaining_bytes)
397  {
399  }
400  }
401  while(braces_open != 0);
402  return loop;
403  }
404  /* evaulate accordingly */
405  if(second_value == VARIABLE_IF)
406  {
407  error_value = interpret_braces(individual,0L,0);
408  }
409  if(second_value == VARIABLE_WHILE)
410  {
411  error_value = interpret_braces(individual,&value[3],location + return_value + 4);
412  }
413  if(error_value == -1)
414  {
415  return -1; /* Enough information presented by this point */
416  }
417  return return_value + 4;
418  }
419  if(individual->main_status == MAIN_NOT_RUN)
420  {
422  }
423  if(VARIABLE_INPUT(second_value, code)) /* x = y + z; */
424  {
425  n_int return_value;
426  if((value[2] != APESCRIPT_OPERATOR) || (value[3] != SYNTAX_EQUALS))
427  {
429  }
430  return_value = interpret_apply(code, individual, &value[4], &output_number, APESCRIPT_SEMICOLON);
431  if(return_value == -1)
432  {
433  return -1; /* Enough information presented by this point */
434  }
435  if(code->sc_input(individual, second_value,output_number) == -1)
436  {
438  }
439  SC_DEBUG_STRING(individual->interpret_data, scdebug_variable(second_value));
440  SC_DEBUG_STRING(individual->interpret_data, " = ");
441  SC_DEBUG_NUMBER(individual->interpret_data, output_number);
442  SC_DEBUG_STRING(individual->interpret_data, " ;");
443  SC_DEBUG_NEWLINE(individual->interpret_data);
444  return return_value + 4;
445  }
447 }
448 
453 static void interpret_start(n_interpret * interp, n_individual_interpret * individual)
454 {
455  n_byte *local_data = interp->binary_code->data;
456  n_int *local_number = interp->number_buffer;
457  n_int *local_variable = individual->variable_references;
458  n_int end_loop = io_bytes_to_int(local_data);
459  n_byte *start_numbers = &local_data[end_loop];
460  n_int local_number_num = io_bytes_to_int(start_numbers);
461  n_int loop = 0;
462  individual->main_status = MAIN_NOT_RUN;
463  individual->braces_count = 0;
464  while(loop++ < BRACES_MAX)
465  {
466  (void)interpret_braces(individual,0L,0); /* No errors in this initialisation */
467  }
468  individual->braces_count = 0;
469  loop = 1;
470  local_number[0] = 0;
471  while(loop < local_number_num)
472  {
473  local_number[loop] = io_bytes_to_int(&start_numbers[loop*SIZEOF_NUMBER_WRITE]);
474  loop++;
475  }
476  loop = 0;
477  while(loop < (VARIABLE_MAX))
478  {
479  local_variable[loop++] = 0;
480  }
481 }
482 
488 static n_int interpret_code(n_interpret * interp, n_individual_interpret * individual)
489 {
490  n_byte *local_data = interp->binary_code->data;
491  n_int loop = SIZEOF_NUMBER_WRITE;
492  n_int cycle_count = 0;
493  n_int end_loop = io_bytes_to_int(local_data);
494 
495  if (individual->interpret_location != 0)
496  {
497  loop = individual->interpret_location;
498  individual->interpret_location = 0;
499  }
500 
501  /* this is the interpret loop */
502  do
503  {
504  n_int result = interpret_syntax(interp, individual, &local_data[loop], loop);
505  if(result == -1)
506  {
507  return -1; /* Enough information presented by this point */
508  }
509 
510  if(result != 0)
511  {
512  loop += result;
513  }
514  else /* This is the while check conditional */
515  {
516  n_brace * local_brace;
517  n_int brace_number = (individual->braces_count - 1);
518  n_byte first_evaluate;
519  if(brace_number < 0)
520  {
522  }
523  local_brace = &(individual->braces[brace_number]);
524  first_evaluate = local_brace->evaluate[0];
525  if(first_evaluate == APESCRIPT_RUN || first_evaluate == APESCRIPT_FUNCTION) /* check the function run */
526  {
527  if(first_evaluate == APESCRIPT_FUNCTION)
528  {
529  local_brace->evaluate[0] = APESCRIPT_RUN;
530  loop = io_bytes_to_int(&(local_brace->evaluate[1]));
531  }
532  else /* end of the run function , put back to where 'run' is called */
533  {
534  loop = io_bytes_to_int(&(local_brace->evaluate[1 + SIZEOF_NUMBER_WRITE]));
535  if(interpret_braces(individual,0L,-1) == -1) /* remove the run function from braces */
536  {
537  return -1; /* Enough information presented by this point */
538  }
539  SC_DEBUG_STRING(individual->interpret_data, "}");
540  SC_DEBUG_DOWN(individual->interpret_data);
541  SC_DEBUG_NEWLINE(individual->interpret_data);
542  }
543  }
544  else
545  {
546  n_int return_value = 0;
547 
548  if(interpret_apply(interp, individual, local_brace->evaluate, &return_value, APESCRIPT_CLOSE_BRACKET) == -1)
549  {
550  return -1; /* Enough information presented by this point */
551  }
552  if(return_value == 0)
553  {
554  if(interpret_braces(individual, 0L, -1) == -1)
555  {
556  return -1; /* Enough information presented by this point */
557  }
558  SC_DEBUG_STRING(individual->interpret_data,"}");
559  SC_DEBUG_DOWN(individual->interpret_data);
560  SC_DEBUG_NEWLINE(individual->interpret_data);
561  loop++;
562  }
563  else
564  {
565  loop = local_brace->braces_start;
566  }
567  }
568  }
569 
570  cycle_count++;
571  }
572  while((loop < end_loop) && (cycle_count < CYCLE_COUNT_RESET) && (individual->leave == 0));
573 
574  if ((individual->leave != 0) || (cycle_count == CYCLE_COUNT_RESET))
575  {
576  individual->interpret_location = loop;
577  }
578  else
579  {
580  if(individual->main_status == MAIN_NOT_RUN)
581  {
583  }
584 
585  SC_DEBUG_OFF(individual->interpret_data); /* turn off debugging after first cycle */
586  }
587 
588  return 0;
589 }
590 
592 {
593  individual->interpret_location = 0;
594  individual->leave = 0;
595  individual->localized_leave = 0;
596 }
597 
603 {
604 #ifdef SCRIPT_DEBUG
606 #endif
607  if (*to_clean == 0L)
608  {
609  return;
610  }
611  if ((*to_clean)->binary_code != 0L)
612  {
613  io_file_free(&((*to_clean)->binary_code));
614  }
615  io_free((void**)to_clean);
616 }
617 
628  void * structure, void * data,
629  script_external * start, script_external * end)
630 {
631  if (code == 0L)
632  {
633  return 0;
634  }
635 
636  individual->interpret_data = data;
637 
638  if (individual->localized_leave)
639  {
640  individual->localized_leave--;
641  } /* the localized_leave = 1 case is where the interpreter was left initially */
642  if (individual->localized_leave)
643  {
644  return 1;
645  }
646 
647  if (individual->interpret_location == 0)
648  {
649  interpret_start(code, individual);
650  if (start != 0L)
651  {
652  (*start)(individual, structure, data);
653  }
654  }
655 
656  if (interpret_code(code, individual) == -1)
657  {
658  return -1;
659  }
660 
661  if (individual->interpret_location == 0)
662  {
663  if ((code != 0L) && (end != 0L))
664  {
665  (*end)(individual, structure, data);
666  }
667  }
668 
669  individual->localized_leave = individual->leave;
670 
671  if (exit_offset > -1)
672  {
673  n_int * variables = individual->variable_references;
674  if (variables[exit_offset] == 0)
675  {
676  return 1;
677  }
678  }
679  return 0;
680 }
681 
682