Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8733 turbocat 1
/*
2
 * Tiny BASIC
3
 * Statement Handling Module
4
 *
5
 * Released as Public Domain by Damian Gareth Walker 2019
6
 * Created: 15-Aug-2019
7
 */
8
 
9
 
10
/* included headers */
11
#include 
12
#include 
13
#include 
14
#include 
15
#include "statement.h"
16
 
17
 
18
/*
19
 * LET Statement Functions
20
 */
21
 
22
 
23
/*
24
 * LET statement constructor
25
 * returns:
26
 *   LetStatementNode*   the created LET statement
27
 */
28
LetStatementNode *statement_create_let (void) {
29
 
30
  /* local variables */
31
  LetStatementNode *letn; /* the created node */
32
 
33
  /* allocate memory and assign safe defaults */
34
  letn = malloc (sizeof (LetStatementNode));
35
  letn->variable = 0;
36
  letn->expression = NULL;
37
 
38
  /* return the LET statement node */
39
  return letn;
40
}
41
 
42
/*
43
 * Destructor for a LET statement
44
 * params:
45
 *   LetStatementNode   *letn   the doomed LET statement.
46
 */
47
void statement_destroy_let (LetStatementNode *letn) {
48
  if (letn->expression)
49
    expression_destroy (letn->expression);
50
  free (letn);
51
}
52
 
53
 
54
/*
55
 * IF Statement Functions
56
 */
57
 
58
 
59
/*
60
 * IF statement constructor
61
 * returns:
62
 *   IfStatementNode*   the created IF statement
63
 */
64
IfStatementNode *statement_create_if (void) {
65
 
66
  /* local variables */
67
  IfStatementNode *ifn; /* the created node */
68
 
69
  /* allocate memory and assign safe defaults */
70
  ifn = malloc (sizeof (IfStatementNode));
71
  ifn->left = ifn->right = NULL;
72
  ifn->op = RELOP_EQUAL;
73
  ifn->statement = NULL;
74
 
75
  /* return the IF statement node */
76
  return ifn;
77
}
78
 
79
/*
80
 * IF statement destructor
81
 * params:
82
 *   IfStatementNode*   ifn   the doomed IF statement
83
 */
84
void statement_destroy_if (IfStatementNode *ifn) {
85
  if (ifn->left)
86
    expression_destroy (ifn->left);
87
  if (ifn->right)
88
    expression_destroy (ifn->right);
89
  if (ifn->statement)
90
    statement_destroy (ifn->statement);
91
  free (ifn);
92
}
93
 
94
 
95
/*
96
 * GOTO Statement Functions
97
 */
98
 
99
 
100
/*
101
 * GOTO Statement Constructor
102
 * returns:
103
 *   GotoStatementNode*   the new GOTO statement
104
 */
105
GotoStatementNode *statement_create_goto (void) {
106
 
107
  /* local variables */
108
  GotoStatementNode *goton; /* the statement to create */
109
 
110
  /* create and initialise the data */
111
  goton = malloc (sizeof (GotoStatementNode));
112
  goton->label = NULL;
113
 
114
  /* return the goto statement */
115
  return goton;
116
}
117
 
118
/*
119
 * GOTO Statement Destructor
120
 * params:
121
 *   GotoStatementNode*   goton   the doomed GOTO statement
122
 */
123
void statement_destroy_goto (GotoStatementNode *goton) {
124
  if (goton) {
125
    if (goton->label)
126
      expression_destroy (goton->label);
127
    free (goton);
128
  }
129
}
130
 
131
 
132
/*
133
 * GOSUB Statement Functions
134
 */
135
 
136
 
137
/*
138
 * GOSUB Statement Constructor
139
 * returns:
140
 *   GosubStatementNode*   the new GOSUB statement
141
 */
142
GosubStatementNode *statement_create_gosub (void) {
143
 
144
  /* local variables */
145
  GosubStatementNode *gosubn; /* the statement to create */
146
 
147
  /* create and initialise the data */
148
  gosubn = malloc (sizeof (GosubStatementNode));
149
  gosubn->label = NULL;
150
 
151
  /* return the gosub statement */
152
  return gosubn;
153
}
154
 
155
/*
156
 * GOSUB Statement Destructor
157
 * params:
158
 *   GosubStatementNode*   gosubn   the doomed GOSUB statement
159
 */
160
void statement_destroy_gosub (GosubStatementNode *gosubn) {
161
  if (gosubn) {
162
    if (gosubn->label)
163
      expression_destroy (gosubn->label);
164
    free (gosubn);
165
  }
166
}
167
 
168
 
169
/*
170
 * PRINT Statement Functions
171
 */
172
 
173
 
174
/*
175
 * PRINT statement constructor
176
 * returns:
177
 *   PrintStatementNode*   the created PRINT statement
178
 */
179
PrintStatementNode *statement_create_print (void) {
180
 
181
  /* local variables */
182
  PrintStatementNode *printn; /* the created node */
183
 
184
  /* allocate memory and assign safe defaults */
185
  printn = malloc (sizeof (PrintStatementNode));
186
  printn->first = NULL;
187
 
188
  /* return the PRINT statement node */
189
  return printn;
190
}
191
 
192
/*
193
 * Destructor for a PRINT statement
194
 * params:
195
 *   PrintStatementNode   *printn   the doomed PRINT statement.
196
 */
197
void statement_destroy_print (PrintStatementNode *printn) {
198
  OutputNode *current, *next;
199
  current = printn->first;
200
  while (current) {
201
    next = current->next;
202
    if (current->class == OUTPUT_STRING)
203
      free (current->output.string);
204
    else if (current->class == OUTPUT_EXPRESSION)
205
      expression_destroy (current->output.expression);
206
    free (current);
207
    current = next;
208
  }
209
  free (printn);
210
}
211
 
212
 
213
/*
214
 * INPUT Statement Functions
215
 */
216
 
217
 
218
/*
219
 * INPUT statement constructor
220
 * returns:
221
 *   InputStatementNode*   initialised INPUT statement data
222
 */
223
InputStatementNode *statement_create_input (void) {
224
 
225
  /* local variables */
226
  InputStatementNode *inputn; /* the new input statement data */
227
 
228
  /* allocate memory and initalise safely */
229
  inputn = malloc (sizeof (InputStatementNode));
230
  inputn->first = NULL;
231
 
232
  /* return the created node */
233
  return inputn;
234
}
235
 
236
/*
237
 * INPUT statement destructor
238
 * params:
239
 *   InputStatementNode*   inputn   the doomed INPUT statement node
240
 */
241
void statement_destroy_input (InputStatementNode *inputn) {
242
 
243
  /* local variables */
244
  VariableListNode
245
    *variable, /* the current variable to destroy */
246
    *next; /* the next variable to destroy */
247
 
248
  /* delete the variables from the variable list, then the input node */
249
  if (inputn) {
250
    variable = inputn->first;
251
    while (variable) {
252
      next = variable->next;
253
      free (variable);
254
      variable = next;
255
    }
256
    free (inputn);
257
  }
258
}
259
 
260
 
261
/*
262
 * Top Level Functions
263
 */
264
 
265
 
266
/*
267
 * Statement constructor
268
 * returns:
269
 *   StatementNode*   the newly-created blank statement
270
 */
271
StatementNode *statement_create (void) {
272
 
273
  /* local variables */
274
  StatementNode *statement; /* the created statement */
275
 
276
  /* allocate memory and set defaults */
277
  statement = malloc (sizeof (StatementNode));
278
  statement->class = STATEMENT_NONE;
279
 
280
  /* return the created statement */
281
  return statement;
282
}
283
 
284
/*
285
 * Statement destructor
286
 * params:
287
 *   StatementNode*   statement   the doomed statement
288
 */
289
void statement_destroy (StatementNode *statement) {
290
  switch (statement->class) {
291
    case STATEMENT_LET:
292
      statement_destroy_let (statement->statement.letn);
293
      break;
294
    case STATEMENT_PRINT:
295
      statement_destroy_print (statement->statement.printn);
296
      break;
297
    case STATEMENT_INPUT:
298
      statement_destroy_input (statement->statement.inputn);
299
      break;
300
    case STATEMENT_IF:
301
      statement_destroy_if (statement->statement.ifn);
302
      break;
303
    case STATEMENT_GOTO:
304
      statement_destroy_goto (statement->statement.goton);
305
      break;
306
    case STATEMENT_GOSUB:
307
      statement_destroy_gosub (statement->statement.gosubn);
308
      break;
309
    default:
310
      break;
311
  }
312
  free (statement);
313
}
314
 
315
 
316
/*
317
 * Program Line Constructor
318
 * returns:
319
 *   ProgramLineNode*   the new program line
320
 */
321
ProgramLineNode *program_line_create (void) {
322
 
323
  /* local variables */
324
  ProgramLineNode *program_line; /* the program line to create */
325
 
326
  /* create and initialise the program line */
327
  program_line = malloc (sizeof (ProgramLineNode));
328
  program_line->label = 0;
329
  program_line->statement = NULL;
330
  program_line->next = NULL;
331
 
332
  /* return the new program line */
333
  return program_line;
334
}
335
 
336
/*
337
 * Program Line Destructor
338
 * params:
339
 *   ProgramLineNode*   program_line   the doomed program line
340
 * params:
341
 *   ProgramLineNode*                  the next program line
342
 */
343
ProgramLineNode *program_line_destroy (ProgramLineNode *program_line) {
344
 
345
  /* local variables */
346
  ProgramLineNode *next = NULL; /* the next program line */
347
 
348
  /* record the next line and destroy this one */
349
  if (program_line) {
350
    next = program_line->next;
351
    if (program_line->statement)
352
      statement_destroy (program_line->statement);
353
    free (program_line);
354
  }
355
 
356
  /* return the line following */
357
  return next;
358
}
359
 
360
/*
361
 * Program Constructor
362
 * returns:
363
 *   ProgramNode*   the constructed program
364
 */
365
ProgramNode *program_create (void) {
366
 
367
  /* local variables */
368
  ProgramNode *program; /* new program */
369
 
370
  /* create and initialise the program */
371
  program = malloc (sizeof (program));
372
  program->first = NULL;
373
 
374
  /* return the new program */
375
  return program;
376
}
377
 
378
/*
379
 * Program Destructor
380
 * params:
381
 *   ProgramNode*   program   the doomed program
382
 */
383
void program_destroy (ProgramNode *program) {
384
 
385
  /* local variables */
386
  ProgramLineNode *program_line; /* the program line to destroy */
387
 
388
  /* destroy the program lines, then the program itself */
389
  program_line = program->first;
390
  while (program_line)
391
    program_line = program_line_destroy (program_line);
392
  free (program);
393
}