Subversion Repositories Kolibri OS

Rev

Rev 8733 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8733 Rev 9234
1
/*
1
/*
2
 * Tiny BASIC
2
 * Tiny BASIC
3
 * Interpreter and Compiler Main Program
3
 * Interpreter and Compiler Main Program
4
 *
4
 *
5
 * Released as Public Domain by Damian Gareth Walker 2019
5
 * Released as Public Domain by Damian Gareth Walker 2019
6
 * Created: 04-Aug-2019
6
 * Created: 04-Aug-2019
7
 */
7
 */
8
 
8
 
9
 
9
 
10
/* included headers */
10
/* included headers */
11
#include 
11
#include 
12
#include 
12
#include 
13
#include 
13
#include 
14
#include "options.h"
14
#include "options.h"
15
#include "errors.h"
15
#include "errors.h"
16
#include "parser.h"
16
#include "parser.h"
17
#include "statement.h"
17
#include "statement.h"
18
#include "interpret.h"
18
#include "interpret.h"
19
#include "formatter.h"
19
#include "formatter.h"
20
#include "generatec.h"
20
#include "generatec.h"
21
 
21
 
22
#ifdef _KOLIBRI
22
#ifdef _KOLIBRI
-
 
23
    #include 
23
    #define KTCC_BIN "/kolibrios/develop/tcc/tcc"
24
    #define KTCC_BIN "/kolibrios/develop/tcc/tcc"
24
    #define KTCC_FLAGS "%s -o %s -lck"  
25
    #define KTCC_FLAGS "-nobss %s -o %s -ltcc -lc.obj"  
25
#endif
26
#endif
26
 
27
 
27
/* static variables */
28
/* static variables */
28
static char *input_filename = NULL; /* name of the input file */
29
static char *input_filename = NULL; /* name of the input file */
29
static enum { /* action to take with parsed program */
30
static enum { /* action to take with parsed program */
30
  OUTPUT_INTERPRET, /* interpret the program */
31
  OUTPUT_INTERPRET, /* interpret the program */
31
  OUTPUT_LST, /* output a formatted listing */
32
  OUTPUT_LST, /* output a formatted listing */
32
  OUTPUT_C, /* output a C program */
33
  OUTPUT_C, /* output a C program */
33
  OUTPUT_EXE /* output an executable */
34
  OUTPUT_EXE /* output an executable */
34
} output = OUTPUT_INTERPRET;
35
} output = OUTPUT_INTERPRET;
35
static ErrorHandler *errors; /* universal error handler */
36
static ErrorHandler *errors; /* universal error handler */
36
static LanguageOptions *loptions; /* language options */
37
static LanguageOptions *loptions; /* language options */
37
 
38
 
38
 
39
 
39
/*
40
/*
40
 * Level 2 Routines
41
 * Level 2 Routines
41
 */
42
 */
42
 
43
 
43
 
44
 
44
/*
45
/*
45
 * Set line number option
46
 * Set line number option
46
 * params:
47
 * params:
47
 *   char*   option   the option supplied on the command line
48
 *   char*   option   the option supplied on the command line
48
 */
49
 */
49
static void set_line_numbers (char *option) {
50
static void set_line_numbers (char *option) {
50
  if (! strncmp ("optional", option, strlen (option)))
51
  if (! strncmp ("optional", option, strlen (option)))
51
    loptions->set_line_numbers (loptions, LINE_NUMBERS_OPTIONAL);
52
    loptions->set_line_numbers (loptions, LINE_NUMBERS_OPTIONAL);
52
  else if (! strncmp ("implied", option, strlen (option)))
53
  else if (! strncmp ("implied", option, strlen (option)))
53
    loptions->set_line_numbers (loptions, LINE_NUMBERS_IMPLIED);
54
    loptions->set_line_numbers (loptions, LINE_NUMBERS_IMPLIED);
54
  else if (! strncmp ("mandatory", option, strlen (option)))
55
  else if (! strncmp ("mandatory", option, strlen (option)))
55
    loptions->set_line_numbers (loptions, LINE_NUMBERS_MANDATORY);
56
    loptions->set_line_numbers (loptions, LINE_NUMBERS_MANDATORY);
56
  else
57
  else
57
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
58
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
58
}
59
}
59
 
60
 
60
/*
61
/*
61
 * Set line number limit
62
 * Set line number limit
62
 * params:
63
 * params:
63
 *   char*   option   the option supplied on the command line
64
 *   char*   option   the option supplied on the command line
64
 */
65
 */
65
static void set_line_limit (char *option) {
66
static void set_line_limit (char *option) {
66
  int limit; /* the limit contained in the option */
67
  int limit; /* the limit contained in the option */
67
  if (sscanf (option, "%d", &limit))
68
  if (sscanf (option, "%d", &limit))
68
    loptions->set_line_limit (loptions, limit);
69
    loptions->set_line_limit (loptions, limit);
69
  else
70
  else
70
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
71
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
71
}
72
}
72
 
73
 
73
/*
74
/*
74
 * Set comment option
75
 * Set comment option
75
 * params:
76
 * params:
76
 *   char*   option   the option supplied on the command line
77
 *   char*   option   the option supplied on the command line
77
 */
78
 */
78
static void set_comments (char *option) {
79
static void set_comments (char *option) {
79
  if (! strncmp ("enabled", option, strlen (option)))
80
  if (! strncmp ("enabled", option, strlen (option)))
80
    loptions->set_comments (loptions, COMMENTS_ENABLED);
81
    loptions->set_comments (loptions, COMMENTS_ENABLED);
81
  else if (! strncmp ("disabled", option, strlen (option)))
82
  else if (! strncmp ("disabled", option, strlen (option)))
82
    loptions->set_comments (loptions, COMMENTS_DISABLED);
83
    loptions->set_comments (loptions, COMMENTS_DISABLED);
83
  else
84
  else
84
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
85
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
85
}
86
}
86
 
87
 
87
/*
88
/*
88
 * Set the output options
89
 * Set the output options
89
 * params:
90
 * params:
90
 *   char*   option   the option supplied on the command line
91
 *   char*   option   the option supplied on the command line
91
 */
92
 */
92
static void set_output (char *option) {
93
static void set_output (char *option) {
93
  if (! strcmp ("lst", option))
94
  if (! strcmp ("lst", option))
94
    output = OUTPUT_LST;
95
    output = OUTPUT_LST;
95
  else if (! strcmp ("c", option))
96
  else if (! strcmp ("c", option))
96
    output = OUTPUT_C;
97
    output = OUTPUT_C;
97
  else if (! strcmp ("exe", option))
98
  else if (! strcmp ("exe", option))
98
    output = OUTPUT_EXE;
99
    output = OUTPUT_EXE;
99
  else
100
  else
100
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
101
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
101
}
102
}
102
 
103
 
103
/*
104
/*
104
 * Set the GOSUB stack limit option
105
 * Set the GOSUB stack limit option
105
 * params:
106
 * params:
106
 *   char*   option   the option supplied on the command line
107
 *   char*   option   the option supplied on the command line
107
 */
108
 */
108
static void set_gosub_limit (char *option) {
109
static void set_gosub_limit (char *option) {
109
  int limit; /* the limit contained in the option */
110
  int limit; /* the limit contained in the option */
110
  if (sscanf (option, "%d", &limit))
111
  if (sscanf (option, "%d", &limit))
111
    loptions->set_gosub_limit (loptions, limit);
112
    loptions->set_gosub_limit (loptions, limit);
112
  else
113
  else
113
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
114
    errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
114
}
115
}
115
 
116
 
116
 
117
 
117
/*
118
/*
118
 * Level 1 Routines
119
 * Level 1 Routines
119
 */
120
 */
120
 
121
 
121
 
122
 
122
/*
123
/*
123
 * Process the command line options
124
 * Process the command line options
124
 * params:
125
 * params:
125
 *   int     argc   number of arguments on the command line
126
 *   int     argc   number of arguments on the command line
126
 *   char**  argv   the arguments
127
 *   char**  argv   the arguments
127
 */
128
 */
128
static void set_options (int argc, char **argv) {
129
static void set_options (int argc, char **argv) {
129
 
130
 
130
  /* local variables */
131
  /* local variables */
131
  int argn; /* argument number count */
132
  int argn; /* argument number count */
132
 
133
 
133
  /* loop through all parameters */
134
  /* loop through all parameters */
134
  for (argn = 1; argn < argc && ! errors->get_code (errors); ++argn) {
135
  for (argn = 1; argn < argc && ! errors->get_code (errors); ++argn) {
135
 
136
 
136
    /* scan for line number options */
137
    /* scan for line number options */
137
    if (! strncmp (argv[argn], "-n", 2))
138
    if (! strncmp (argv[argn], "-n", 2))
138
      set_line_numbers (&argv[argn][2]);
139
      set_line_numbers (&argv[argn][2]);
139
    else if (! strncmp (argv[argn], "--line-numbers=", 15))
140
    else if (! strncmp (argv[argn], "--line-numbers=", 15))
140
      set_line_numbers (&argv[argn][15]);
141
      set_line_numbers (&argv[argn][15]);
141
 
142
 
142
    /* scan for line number limit */
143
    /* scan for line number limit */
143
    else if (! strncmp (argv[argn], "-N", 2))
144
    else if (! strncmp (argv[argn], "-N", 2))
144
      set_line_limit (&argv[argn][2]);
145
      set_line_limit (&argv[argn][2]);
145
    else if (! strncmp (argv[argn], "--line-limit=", 13))
146
    else if (! strncmp (argv[argn], "--line-limit=", 13))
146
      set_line_limit (&argv[argn][13]);
147
      set_line_limit (&argv[argn][13]);
147
 
148
 
148
    /* scan for comment option */
149
    /* scan for comment option */
149
    else if (! strncmp (argv[argn], "-o", 2))
150
    else if (! strncmp (argv[argn], "-o", 2))
150
      set_comments (&argv[argn][2]);
151
      set_comments (&argv[argn][2]);
151
    else if (! strncmp (argv[argn], "--comments=", 11))
152
    else if (! strncmp (argv[argn], "--comments=", 11))
152
      set_comments (&argv[argn][11]);
153
      set_comments (&argv[argn][11]);
153
 
154
 
154
    /* scan for output option */
155
    /* scan for output option */
155
    else if (! strncmp (argv[argn], "-O", 2))
156
    else if (! strncmp (argv[argn], "-O", 2))
156
      set_output (&argv[argn][2]);
157
      set_output (&argv[argn][2]);
157
    else if (! strncmp (argv[argn], "--output=", 9))
158
    else if (! strncmp (argv[argn], "--output=", 9))
158
      set_output (&argv[argn][9]);
159
      set_output (&argv[argn][9]);
159
 
160
 
160
    /* scan for gosub stack limit */
161
    /* scan for gosub stack limit */
161
    else if (! strncmp (argv[argn], "-g", 2))
162
    else if (! strncmp (argv[argn], "-g", 2))
162
      set_gosub_limit (&argv[argn][2]);
163
      set_gosub_limit (&argv[argn][2]);
163
    else if (! strncmp (argv[argn], "--gosub-limit=", 14))
164
    else if (! strncmp (argv[argn], "--gosub-limit=", 14))
164
      set_gosub_limit (&argv[argn][14]);
165
      set_gosub_limit (&argv[argn][14]);
165
 
166
 
166
    /* accept filename */
167
    /* accept filename */
167
    else if (! input_filename)
168
    else if (! input_filename)
168
      input_filename = argv[argn];
169
      input_filename = argv[argn];
169
 
170
 
170
    /* raise an error upon illegal option */
171
    /* raise an error upon illegal option */
171
    else
172
    else
172
      errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
173
      errors->set_code (errors, E_BAD_COMMAND_LINE, 0, 0);
173
  }
174
  }
174
}
175
}
175
 
176
 
176
/*
177
/*
177
 * Output a formatted program listing
178
 * Output a formatted program listing
178
 * params:
179
 * params:
179
 *   ProgramNode*   program   the program to output
180
 *   ProgramNode*   program   the program to output
180
 */
181
 */
181
static void output_lst (ProgramNode *program) {
182
static void output_lst (ProgramNode *program) {
182
 
183
 
183
  /* local variables */
184
  /* local variables */
184
  FILE *output; /* the output file */
185
  FILE *output; /* the output file */
185
  char *output_filename; /* the output filename */
186
  char *output_filename; /* the output filename */
186
  Formatter *formatter; /* the formatter object */
187
  Formatter *formatter; /* the formatter object */
187
 
188
 
188
  /* ascertain the output filename */
189
  /* ascertain the output filename */
189
  output_filename = malloc (strlen (input_filename) + 5);
190
  output_filename = malloc (strlen (input_filename) + 5);
190
  if (output_filename) {
191
  if (output_filename) {
191
 
192
 
192
    /* open the output file */
193
    /* open the output file */
193
    sprintf (output_filename, "%s.lst", input_filename);
194
    sprintf (output_filename, "%s.lst", input_filename);
194
    if ((output = fopen (output_filename, "w"))) {
195
    if ((output = fopen (output_filename, "w"))) {
195
 
196
 
196
      /* write to the output file */
197
      /* write to the output file */
197
      formatter = new_Formatter (errors);
198
      formatter = new_Formatter (errors);
198
      if (formatter) {
199
      if (formatter) {
199
        formatter->generate (formatter, program);
200
        formatter->generate (formatter, program);
200
        if (formatter->output)
201
        if (formatter->output)
201
          fprintf (output, "%s", formatter->output);
202
          fprintf (output, "%s", formatter->output);
202
        formatter->destroy (formatter);
203
        formatter->destroy (formatter);
203
      }
204
      }
204
      fclose (output);
205
      fclose (output);
205
    }
206
    }
206
 
207
 
207
    /* deal with errors */
208
    /* deal with errors */
208
    else
209
    else
209
      errors->set_code (errors, E_FILE_NOT_FOUND, 0, 0);
210
      errors->set_code (errors, E_FILE_NOT_FOUND, 0, 0);
210
 
211
 
211
    /* free the output filename */
212
    /* free the output filename */
212
    free (output_filename);
213
    free (output_filename);
213
  }
214
  }
214
 
215
 
215
  /* deal with out of memory error */
216
  /* deal with out of memory error */
216
  else
217
  else
217
    errors->set_code (errors, E_MEMORY, 0, 0);
218
    errors->set_code (errors, E_MEMORY, 0, 0);
218
}
219
}
219
 
220
 
220
/*
221
/*
221
 * Output a C source file
222
 * Output a C source file
222
 * params:
223
 * params:
223
 *   ProgramNode*   program   the parsed program
224
 *   ProgramNode*   program   the parsed program
224
 */
225
 */
225
static void output_c (ProgramNode *program) {
226
static void output_c (ProgramNode *program) {
226
 
227
 
227
  /* local variables */
228
  /* local variables */
228
  FILE *output; /* the output file */
229
  FILE *output; /* the output file */
229
  char *output_filename; /* the output filename */
230
  char *output_filename; /* the output filename */
230
  CProgram *c_program; /* the C program */
231
  CProgram *c_program; /* the C program */
231
 
232
 
232
  /* open the output file */
233
  /* open the output file */
233
  output_filename = malloc (strlen (input_filename) + 5);
234
  output_filename = malloc (strlen (input_filename) + 5);
234
  sprintf (output_filename, "%s.c", input_filename);
235
  sprintf (output_filename, "%s.c", input_filename);
235
  if ((output = fopen (output_filename, "w"))) {
236
  if ((output = fopen (output_filename, "w"))) {
236
 
237
 
237
    /* write to the output file */
238
    /* write to the output file */
238
    c_program = new_CProgram (errors, loptions);
239
    c_program = new_CProgram (errors, loptions);
239
    if (c_program) {
240
    if (c_program) {
240
      c_program->generate (c_program, program);
241
      c_program->generate (c_program, program);
241
      if (c_program->c_output)
242
      if (c_program->c_output)
242
        fprintf (output, "%s", c_program->c_output);
243
        fprintf (output, "%s", c_program->c_output);
243
      c_program->destroy (c_program);
244
      c_program->destroy (c_program);
244
    }
245
    }
245
    fclose (output);
246
    fclose (output);
246
  }
247
  }
247
 
248
 
248
  /* deal with errors */
249
  /* deal with errors */
249
  else
250
  else
250
    errors->set_code (errors, E_FILE_NOT_FOUND, 0, 0);
251
    errors->set_code (errors, E_FILE_NOT_FOUND, 0, 0);
251
 
252
 
252
  /* clean up allocated memory */
253
  /* clean up allocated memory */
253
  free (output_filename);
254
  free (output_filename);
254
}
255
}
255
 
256
 
256
/*
257
/*
257
 * Invoke a compiler to turn a C source file into an executable
258
 * Invoke a compiler to turn a C source file into an executable
258
 * params:
259
 * params:
259
 *   char*   basic_filename   The BASIC program's name
260
 *   char*   basic_filename   The BASIC program's name
260
 */
261
 */
261
static void output_exe (char *command, char *basic_filename) {
262
static void output_exe (char *command, char *basic_filename) {
262
 
263
 
263
  /* local variables */
264
  /* local variables */
264
  char
265
  char
265
    c_filename[256], /* the name of the C source */
266
    c_filename[256], /* the name of the C source */
266
    exe_filename[256], /* the base name of the executable */
267
    exe_filename[256], /* the base name of the executable */
267
    final_command[1024], /* the constructed compiler command */
268
    final_command[1024], /* the constructed compiler command */
268
    *ext, /* position of extension character '.' in filename */
269
    *ext, /* position of extension character '.' in filename */
269
    *src, /* source pointer for string copying */
270
    *src, /* source pointer for string copying */
270
    *dst; /* destination pointer for string copying */
271
    *dst; /* destination pointer for string copying */
271
 
272
 
272
  /* work out the C and EXE filenames */
273
  /* work out the C and EXE filenames */
273
  sprintf (c_filename, "%s.c", basic_filename);
274
  sprintf (c_filename, "%s.c", basic_filename);
274
  strcpy (exe_filename, basic_filename);
275
  strcpy (exe_filename, basic_filename);
275
  if ((ext = strchr (exe_filename, '.')))
276
  if ((ext = strchr (exe_filename, '.')))
276
    *ext = '\0';
277
    *ext = '\0';
277
  else
278
  else
278
    strcat (exe_filename, ".out");
279
    strcat (exe_filename, ".out");
279
 
280
 
280
#ifndef _KOLIBRI
281
#ifndef _KOLIBRI
281
  /* build the compiler command */
282
  /* build the compiler command */
282
  src = command;
283
  src = command;
283
  dst = final_command;
284
  dst = final_command;
284
  while (*src) {
285
  while (*src) {
285
    if (! strncmp (src, "$(TARGET)", strlen ("$(TARGET)"))) {
286
    if (! strncmp (src, "$(TARGET)", strlen ("$(TARGET)"))) {
286
      strcpy (dst, exe_filename);
287
      strcpy (dst, exe_filename);
287
      dst += strlen (exe_filename);
288
      dst += strlen (exe_filename);
288
      src += strlen ("$(TARGET)");
289
      src += strlen ("$(TARGET)");
289
    } else if (! strncmp (src, "$(SOURCE)", strlen ("$(SOURCE)"))) {
290
    } else if (! strncmp (src, "$(SOURCE)", strlen ("$(SOURCE)"))) {
290
      strcpy (dst, c_filename);
291
      strcpy (dst, c_filename);
291
      dst += strlen (c_filename);
292
      dst += strlen (c_filename);
292
      src += strlen ("$(SOURCE)");
293
      src += strlen ("$(SOURCE)");
293
    } else
294
    } else
294
      *(dst++) = *(src++);
295
      *(dst++) = *(src++);
295
  }
296
  }
296
  *dst = '\0';
297
  *dst = '\0';
297
 
298
 
298
  /* run the compiler command */
299
  /* run the compiler command */
299
  system (final_command);
300
  system (final_command);
300
#else
301
#else
301
  sprintf(final_command, KTCC_FLAGS, c_filename, exe_filename);
302
  sprintf(final_command, KTCC_FLAGS, c_filename, exe_filename);
302
  if(!_ksys_exec(KTCC_BIN, final_command)){
303
  if(!_ksys_exec(KTCC_BIN, final_command)){
303
    printf(final_command);
-
 
304
  }else{
-
 
305
    printf("Bad command: %s %s\n", KTCC_BIN, final_command);
304
    printf("Bad command: %s %s\n", KTCC_BIN, final_command);
306
    exit(0);
305
    exit(0);
307
  }
306
  }
308
#endif
307
#endif
309
}
308
}
310
 
-
 
311
 
309
 
312
/*
310
/*
313
 * Top Level Routine
311
 * Top Level Routine
314
 */
312
 */
315
 
313
 
316
 
314
 
317
/*
315
/*
318
 * Main Program
316
 * Main Program
319
 * params:
317
 * params:
320
 *   int     argc   number of arguments on the command line
318
 *   int     argc   number of arguments on the command line
321
 *   char**  argv   the arguments
319
 *   char**  argv   the arguments
322
 * returns:
320
 * returns:
323
 *   int            any error code from processing/running the program
321
 *   int            any error code from processing/running the program
324
 */
322
 */
325
int main (int argc, char **argv) {
323
int main (int argc, char **argv) {
326
  /* local variables */
324
  /* local variables */
327
  FILE *input; /* input file */
325
  FILE *input; /* input file */
328
  ProgramNode *program; /* the parsed program */
326
  ProgramNode *program; /* the parsed program */
329
  ErrorCode code; /* error returned */
327
  ErrorCode code; /* error returned */
330
  Parser *parser; /* parser object */
328
  Parser *parser; /* parser object */
331
  Interpreter *interpreter; /* interpreter object */
329
  Interpreter *interpreter; /* interpreter object */
332
  char
330
  char
333
    *error_text, /* error text message */
331
    *error_text, /* error text message */
334
    *command; /* command for compilation */
332
    *command; /* command for compilation */
335
 
333
 
336
  /* interpret the command line arguments */
334
  /* interpret the command line arguments */
337
  errors = new_ErrorHandler ();
335
  errors = new_ErrorHandler ();
338
  loptions = new_LanguageOptions ();
336
  loptions = new_LanguageOptions ();
339
  set_options (argc, argv);
337
  set_options (argc, argv);
340
 
338
 
341
  /* give usage if filename not given */
339
  /* give usage if filename not given */
342
  if (! input_filename) {
340
  if (! input_filename) {
343
    printf ("Usage: tinybas [OPTIONS] INPUT-FILE\n");
341
    printf ("Usage: tinybas [OPTIONS] INPUT-FILE\n");
344
    errors->destroy (errors);
342
    errors->destroy (errors);
345
    loptions->destroy (loptions);
343
    loptions->destroy (loptions);
346
    return 0;
344
    return 0;
347
  }
345
  }
348
  /* otherwise attempt to open the file */
346
  /* otherwise attempt to open the file */
349
  if (!(input = fopen (input_filename, "r"))) {
347
  if (!(input = fopen (input_filename, "r"))) {
350
    printf ("Error: cannot open file %s\n", input_filename);
348
    printf ("Error: cannot open file %s\n", input_filename);
351
    errors->destroy (errors);
349
    errors->destroy (errors);
352
    loptions->destroy (loptions);
350
    loptions->destroy (loptions);
353
    return E_FILE_NOT_FOUND;
351
    return E_FILE_NOT_FOUND;
354
  }
352
  }
355
 
353
 
356
  /* get the parse tree */
354
  /* get the parse tree */
357
  parser = new_Parser (errors, loptions, input);
355
  parser = new_Parser (errors, loptions, input);
358
  program = parser->parse (parser);
356
  program = parser->parse (parser);
359
  parser->destroy (parser);
357
  parser->destroy (parser);
360
  fclose (input);
358
  fclose (input);
361
 
359
 
362
  /* deal with errors */
360
  /* deal with errors */
363
  if ((code = errors->get_code (errors))) {
361
  if ((code = errors->get_code (errors))) {
364
    error_text = errors->get_text (errors);
362
    error_text = errors->get_text (errors);
365
    printf ("Parse error: %s\n", error_text);
363
    printf ("Parse error: %s\n", error_text);
366
    free (error_text);
364
    free (error_text);
367
    loptions->destroy (loptions);
365
    loptions->destroy (loptions);
368
    errors->destroy (errors);
366
    errors->destroy (errors);
369
    return code;
367
    return code;
370
  }
368
  }
371
 
369
 
372
  /* perform the desired action */
370
  /* perform the desired action */
373
  switch (output) {
371
  switch (output) {
374
    case OUTPUT_INTERPRET:
372
    case OUTPUT_INTERPRET:
375
      interpreter = new_Interpreter (errors, loptions);
373
      interpreter = new_Interpreter (errors, loptions);
376
      interpreter->interpret (interpreter, program);
374
      interpreter->interpret (interpreter, program);
377
      interpreter->destroy (interpreter);
375
      interpreter->destroy (interpreter);
378
      if ((code = errors->get_code (errors))) {
376
      if ((code = errors->get_code (errors))) {
379
        error_text = errors->get_text (errors);
377
        error_text = errors->get_text (errors);
380
        printf ("Runtime error: %s\n", error_text);
378
        printf ("Runtime error: %s\n", error_text);
381
        free (error_text);
379
        free (error_text);
382
      }
380
      }
383
      break;
381
      break;
384
    case OUTPUT_LST:
382
    case OUTPUT_LST:
385
      output_lst (program);
383
      output_lst (program);
386
      break;
384
      break;
387
    case OUTPUT_C:
385
    case OUTPUT_C:
388
      output_c (program);
386
      output_c (program);
389
      break;
387
      break;
390
    case OUTPUT_EXE:
388
    case OUTPUT_EXE:
391
      
389
      
392
    #ifndef _KOLIBRI 
390
    #ifndef _KOLIBRI 
393
        if ((command = getenv ("TBEXE"))) {
391
        if ((command = getenv ("TBEXE"))) {
394
            output_c (program);
392
            output_c (program);
395
            output_exe (command, input_filename);
393
            output_exe (command, input_filename);
396
        } else {
394
        } else {
397
            printf ("TBEXE not set.\n");
395
            printf ("TBEXE not set.\n");
398
            break;
396
            break;
399
        }
397
        }
400
    #else
398
    #else
401
        output_c (program);
399
        output_c (program);
402
        output_exe (NULL, input_filename);
400
        output_exe (NULL, input_filename);
403
        break;
401
        break;
404
    #endif
402
    #endif
405
  }
403
  }
406
  /* clean up and return success */
404
  /* clean up and return success */
407
  program_destroy (program);
405
  program_destroy (program);
408
  loptions->destroy (loptions);
406
  loptions->destroy (loptions);
409
  errors->destroy (errors);
407
  errors->destroy (errors);
410
  exit(0);
408
  exit(0);
411
}
409
}