Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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 <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <ctype.h>
  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. }
  394.