Added new port TinyBasic

(An improved version in conjunction with ktcc can generate executable files.)

git-svn-id: svn://kolibrios.org@8733 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
turbocat
2021-05-23 15:55:49 +00:00
parent 4a09257a8f
commit 43795ab11a
34 changed files with 7387 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
/*
* Tiny BASIC Interpreter and Compiler Project
* Common service routines module
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 20-Sep-2019
*/
#ifndef __COMMON_H__
#define __COMMON_H__
/*
* Function Declarations
*/
/*
* Portable case-insensitive comparison
* params:
* char* a string to compare
* char* b string to compare to
* returns:
* int -1 if a<b, 0 if a==b, 1 if a>b
*/
int tinybasic_strcmp (char *a, char *b);
#endif

View File

@@ -0,0 +1,67 @@
/*
* Tiny BASIC
* Error Handling Header
*
* Copyright (C) Damian Gareth Walker 2019
* Created: 15-Aug-2019
*/
#ifndef __ERRORS_H__
#define __ERRORS_H__
/*
* Data Definitions
*/
/* error codes */
typedef enum {
E_NONE, /* no error; everything is fine */
E_INVALID_LINE_NUMBER, /* line number is invalid */
E_UNRECOGNISED_COMMAND, /* command was not recognised */
E_INVALID_VARIABLE, /* variable expected but something else encountered */
E_INVALID_ASSIGNMENT, /* = expected but something else encountered */
E_INVALID_EXPRESSION, /* an invalid expression was encountered */
E_MISSING_RIGHT_PARENTHESIS, /* Encountered "(" without corresponding ")" */
E_INVALID_PRINT_OUTPUT, /* failed to parse print output */
E_BAD_COMMAND_LINE, /* error on invocation */
E_FILE_NOT_FOUND, /* cannot open source file */
E_INVALID_OPERATOR, /* unrecognised operator */
E_THEN_EXPECTED, /* didn't find the expected THEN after an IF */
E_UNEXPECTED_PARAMETER, /* more parameters encountered than expected */
E_RETURN_WITHOUT_GOSUB, /* return encountered without a GOSUB */
E_DIVIDE_BY_ZERO, /* an attempt to divide by zero */
E_OVERFLOW, /* integer is out of range */
E_MEMORY, /* out of memory */
E_TOO_MANY_GOSUBS, /* recursive GOSUBs exceeded the stack size */
E_LAST /* placeholder */
} ErrorCode;
/* error handler structure */
typedef struct error_handler ErrorHandler;
typedef struct error_handler {
void *data; /* private data */
void (*set_code) (ErrorHandler *, ErrorCode, int, int);
ErrorCode (*get_code) (ErrorHandler *);
int (*get_line) (ErrorHandler *);
int (*get_label) (ErrorHandler *);
char *(*get_text) (ErrorHandler *);
void (*destroy) (ErrorHandler *);
} ErrorHandler;
/*
* Constructors
*/
/*
* Principal constructor
* returns:
* ErrorHandler* the new error handler object
*/
ErrorHandler *new_ErrorHandler (void);
#endif

View File

@@ -0,0 +1,176 @@
/*
* Tiny BASIC
* Expression Handling Header
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 16-Aug-2019
*/
#ifndef __EXPRESSION_H__
#define __EXPRESSION_H__
/* Forward Declarations */
typedef struct expression_node ExpressionNode;
typedef struct right_hand_term RightHandTerm;
typedef struct term_node TermNode;
typedef struct right_hand_factor RightHandFactor;
/*
* Data Definitions - Factors
*/
/* The different classes of factor */
typedef enum {
FACTOR_NONE, /* class as yet undetermined */
FACTOR_VARIABLE, /* a variable */
FACTOR_VALUE, /* an integer value */
FACTOR_EXPRESSION /* a bracketed expression */
} FactorClass;
/* The signs */
typedef enum {
SIGN_POSITIVE,
SIGN_NEGATIVE
} SignClass;
/* A factor */
typedef struct {
FactorClass class; /* what kind of factor is this? */
SignClass sign; /* which sign, positive or negative? */
union {
int variable;
int value;
ExpressionNode *expression;
} data;
} FactorNode;
/* The term operators */
typedef enum {
TERM_OPERATOR_NONE, /* single-factor term */
TERM_OPERATOR_MULTIPLY, /* multiply */
TERM_OPERATOR_DIVIDE /* divide */
} TermOperator;
/* the operator and right-hand part of a term */
typedef struct right_hand_factor {
TermOperator op; /* the operator to apply: muliply or divide */
FactorNode *factor; /* the factor to multiply or divide by */
RightHandFactor *next; /* the next part of the term, if any */
} RightHandFactor;
/* A term */
typedef struct term_node {
FactorNode *factor; /* the first factor of an expression */
RightHandFactor *next; /* the right side term, if any */
} TermNode;
/* Expression Operator */
typedef enum {
EXPRESSION_OPERATOR_NONE, /* single-term expression */
EXPRESSION_OPERATOR_PLUS, /* addition */
EXPRESSION_OPERATOR_MINUS /* substraction */
} ExpressionOperator;
/* the operator and right-hand part of an expression */
typedef struct right_hand_term {
ExpressionOperator op; /* the operator to apply: plus or minus */
TermNode *term; /* the term to add or subtract */
RightHandTerm *next; /* next part of the expression, if any */
} RightHandTerm;
/* An expression */
typedef struct expression_node {
TermNode *term; /* The first term of an expression */
RightHandTerm *next; /* the right side expression, if any */
} ExpressionNode;
/*
* Function Declarations
*/
/*
* Constructor for a factor
* returns:
* FactorNode* the new factor
*/
FactorNode *factor_create (void);
/*
* Destructor for a factor
* params:
* FactorNode* factor the doomed factor
*/
void factor_destroy (FactorNode *factor);
/*
* Constructor for a right-hand factor of a term
* returns:
* RightHandFactor* the new RH factor of a term
*/
RightHandFactor *rhfactor_create (void);
/*
* Recursive destructor for a right-hand factor of a term
* params:
* RightHandFactor* rhterm the doomed RH factor of a term
*/
void rhfactor_destroy (RightHandFactor *rhterm);
/*
* Constructor for a term
* returns:
* TermNode* the new term
*/
TermNode *term_create (void);
/*
* Destructor for a term
* params:
* TermNode* term the doomed term
*/
void term_destroy (TermNode *term);
/*
* Constructor for a right-hand expression
* returns:
* RightHandTerm* the RH term of an expression
*/
RightHandTerm *rhterm_create (void);
/*
* Recursive destructor for a right-hand term of an expression
* params:
* RightHandTerm* rhexpression the doomed RH expression
*/
void rhterm_destroy (RightHandTerm *rhterm);
/*
* Constructor for an expression
* returns:
* ExpressionNode* the new expression
*/
ExpressionNode *expression_create (void);
/*
* Destructor for a factor
* params:
* FactorNode* factor the doomed factor
*/
void factor_destroy (FactorNode *factor);
/*
* Destructor for a expression
* params:
* ExpressionNode* expression the doomed expression
*/
void expression_destroy (ExpressionNode *expression);
#endif

View File

@@ -0,0 +1,66 @@
/*
* Tiny BASIC
* Listing Output Header
*
* Released as Public Domain by Damian Gareth Walker, 2019
* Created: 18-Sep-2019
*/
#ifndef __FORMATTER_H__
#define __FORMATTER_H__
/* included headers */
#include "errors.h"
#include "statement.h"
/*
* Data Declarations
*/
/* Formatter Class */
typedef struct formatter_data FormatterData;
typedef struct formatter Formatter;
typedef struct formatter {
/* Properties */
FormatterData *priv; /* private data */
char *output; /* the formatted output */
/*
* Create a formatted version of the program
* params:
* Formatter* the formatter
* ProgramNode* the syntax tree
* returns:
* char* the formatted BASIC program
*/
void (*generate) (Formatter *, ProgramNode *);
/*
* Destroy the formatter when no longer needed
* params:
* Formatter* the doomed formatter
*/
void (*destroy) (Formatter *);
} Formatter;
/*
* Function Declarations
*/
/*
* The Formatter constructor
* returns:
* Formatter* the new formatter
*/
Formatter *new_Formatter (ErrorHandler *errors);
#endif

View File

@@ -0,0 +1,50 @@
/*
* Tiny BASIC Interpreter and Compiler Project
* C Output Header
*
* Copyright (C) Damian Gareth Walker 2019
* Created: 03-Oct-2019
*/
#ifndef __GENERATEC_H__
#define __GENERATEC_H__
/* included headers */
#include "errors.h"
#include "options.h"
/* forward references */
typedef struct c_program CProgram;
/* object structure */
typedef struct c_program {
void *private_data; /* private data */
char *c_output; /* the generated C code */
void (*generate) (CProgram *, ProgramNode *); /* generate function */
void (*destroy) (CProgram *); /* destructor */
} CProgram;
/*
* Function Declarations
*/
/*
* Constructor
* params:
* ErrorHandler* compiler_errors the error handler
* LanguageOptions* compiler_options language options
* changes:
* CProgram* this the object being created
* Private* data the object's private data
* returns:
* CProgram* the created object
*/
CProgram *new_CProgram (ErrorHandler *compiler_errors,
LanguageOptions *compiler_options);
#endif

View File

@@ -0,0 +1,64 @@
/*
* Tiny BASIC Interpreter and Compiler Project
* Interpreter header
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 23-Aug-2019
*/
#ifndef __INTERPRET_H__
#define __INTERPRET_H__
/* included headers */
#include "errors.h"
#include "options.h"
#include "statement.h"
/*
* Data Declarations
*/
/* the interpreter object */
typedef struct interpreter_data InterpreterData;
typedef struct interpreter Interpreter;
typedef struct interpreter {
/* Properties */
InterpreterData *priv; /* private data */
/*
* Interpret the program
* params:
* Interpreter* the interpreter to use
* ProgramNode* the program to interpret
*/
void (*interpret) (Interpreter *, ProgramNode *);
/*
* Destructor
* params:
* Interpreter* the doomed interpreter
*/
void (*destroy) (Interpreter *);
} Interpreter;
/*
* Function Declarations
*/
/*
* Constructor
* returns:
* Interpreter* the new interpreter
*/
Interpreter *new_Interpreter (ErrorHandler *errors, LanguageOptions *options);
#endif

View File

@@ -0,0 +1,61 @@
/*
* Tiny BASIC Interpreter and Compiler Project
* Language Options Header
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 18-Aug-2019
*/
#ifndef __OPTIONS_H__
#define __OPTIONS_H__
/*
* Data Definitions
*/
/* line number options */
typedef enum {
LINE_NUMBERS_OPTIONAL, /* they are optional numeric labels */
LINE_NUMBERS_IMPLIED, /* missing line numbers are implied */
LINE_NUMBERS_MANDATORY /* every line requires a number in sequence */
} LineNumberOption;
/* comment options */
typedef enum {
COMMENTS_ENABLED, /* comments and blank lines are allowed */
COMMENTS_DISABLED /* comments and blank lines are not allowed */
} CommentOption;
/* language options */
typedef struct language_options LanguageOptions;
typedef struct language_options {
void *data; /* private data */
void (*set_line_numbers) (LanguageOptions *, LineNumberOption);
void (*set_line_limit) (LanguageOptions *, int);
void (*set_comments) (LanguageOptions *, CommentOption);
void (*set_gosub_limit) (LanguageOptions *, int);
LineNumberOption (*get_line_numbers) (LanguageOptions *);
int (*get_line_limit) (LanguageOptions *);
CommentOption (*get_comments) (LanguageOptions *);
int (*get_gosub_limit) (LanguageOptions *);
void (*destroy) (LanguageOptions *);
} LanguageOptions;
/*
* Function Declarations
*/
/*
* Constructor for language options
* returns:
* LanguageOptions* the new language options object
*/
LanguageOptions *new_LanguageOptions (void);
#endif

View File

@@ -0,0 +1,93 @@
/*
* Tiny BASIC
* Parser Header
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 08-Aug-2019
*/
#ifndef __PARSER_H__
#define __PARSER_H__
/* pre-requisite headers */
#include "statement.h"
#include "errors.h"
#include "options.h"
#include "tokeniser.h"
/*
* Data Declarations
*/
/* the parser */
typedef struct parser_data ParserData;
typedef struct parser Parser;
typedef struct parser {
/* Properties */
ParserData *priv; /* parser's private data */
/*
* Public methods
*/
/*
* Parse the whole program
* params:
* Parser* The parser to use
* INPUT* The input file to parse
* returns:
* ProgramNode* The parsed program
*/
ProgramNode *(*parse) (Parser *);
/*
* Return the current source line we're parsing
* params:
* Parser* The parser to use
* returns:
* int the line returned
*/
int (*get_line) (Parser *);
/*
* Return the label of the source line we're parsing
* params:
* Parser* The parser to use
* returns:
* int the label returned
*/
int (*get_label) (Parser *);
/*
* Destroy this parser object
* params:
* Parser* the doomed parser
*/
void (*destroy) (Parser *);
} Parser;
/*
* Function Declarations
*/
/*
* Constructor
* params:
* ErrorHandler* the error handler to use
* LanguageOptions* the language options to use
* FILE* the input file
* returns:
* Parser* the new parser
*/
Parser *new_Parser (ErrorHandler *, LanguageOptions *, FILE *);
#endif

View File

@@ -0,0 +1,233 @@
/*
* Tiny BASIC
* Statement Handling Header
*
* Released as Public Domain by Damian Gareth Walker 2019
* Created: 15-Aug-2019
*/
#ifndef __STATEMENT_H__
#define __STATEMENT_H__
/* Pre-requisite headers */
#include "expression.h"
/* Forward Declarations */
typedef struct program_line_node ProgramLineNode;
typedef struct statement_node StatementNode;
typedef struct output_node OutputNode;
typedef struct variable_list_node VariableListNode;
/*
* Data Definitions
*/
/* The types of output allowed in a PRINT statement */
typedef enum {
OUTPUT_STRING, /* a literal string */
OUTPUT_EXPRESSION /* an expression */
} OutputClass;
/* The relational operators */
typedef enum {
RELOP_EQUAL, /* = */
RELOP_UNEQUAL, /* <> or >< */
RELOP_LESSTHAN, /* < */
RELOP_LESSOREQUAL, /* <= */
RELOP_GREATERTHAN, /* > */
RELOP_GREATEROREQUAL /* >= */
} RelationalOperator;
/* Expressions or strings to output */
typedef struct output_node {
OutputClass class; /* string or expression */
union {
char *string; /* a literal string to output */
ExpressionNode *expression; /* an expression to output */
} output;
OutputNode *next; /* the next output node, if any */
} OutputNode;
/* List of variables to input */
typedef struct variable_list_node {
int variable; /* the variable */
VariableListNode *next; /* next variable, if any */
} VariableListNode;
/*
* Structures for statements in general
*/
/* Let Statement Node */
typedef struct {
int variable; /* the variable to assign, 1..26 for A..Z */
ExpressionNode *expression; /* the expression to assign to it */
} LetStatementNode;
/* If Statement Node */
typedef struct {
ExpressionNode *left; /* the left-hand expression */
RelationalOperator op; /* the comparison operator used */
ExpressionNode *right; /* the right-hand expression */
StatementNode *statement; /* statement to execute if condition is true */
} IfStatementNode;
/* Print Statement Node */
typedef struct {
OutputNode *first; /* the first expression to print */
} PrintStatementNode;
/* Input Statement Node */
typedef struct {
VariableListNode *first; /* the first variable to input */
} InputStatementNode;
/* Goto Statement Node */
typedef struct {
ExpressionNode *label; /* an expression that computes the label */
} GotoStatementNode;
/* Gosub Statement Node */
typedef struct {
ExpressionNode *label; /* an expression that computes the label */
} GosubStatementNode;
/* Statement classes */
typedef enum {
STATEMENT_NONE, /* unknown statement */
STATEMENT_LET, /* LET variable=expression */
STATEMENT_IF, /* IF condition THEN statement */
STATEMENT_GOTO, /* GOTO expression */
STATEMENT_GOSUB, /* GOSUB expression */
STATEMENT_RETURN, /* RETURN */
STATEMENT_END, /* END */
STATEMENT_PRINT, /* PRINT print-list */
STATEMENT_INPUT /* INPUT var-list */
} StatementClass;
/* Common Statement Node */
typedef struct statement_node {
StatementClass class; /* which type of statement this is */
union {
LetStatementNode *letn; /* a LET statement */
IfStatementNode *ifn; /* an IF statement */
GotoStatementNode *goton; /* a GOTO statement */
GosubStatementNode *gosubn; /* a GOSUB statement */
/* a RETURN statement requires no extra data */
/* an END statement requires no extra data */
PrintStatementNode *printn; /* a PRINT statement */
InputStatementNode *inputn; /* an INPUT statement */
} statement;
} StatementNode;
/* a program line */
typedef struct program_line_node {
int label; /* line label */
StatementNode *statement; /* the current statement */
ProgramLineNode *next; /* the next statement */
} ProgramLineNode;
/* the program */
typedef struct {
ProgramLineNode *first; /* first program statement */
} ProgramNode;
/*
* Function Declarations
*/
/*
* LET statement constructor
* returns:
* LetStatementNode* the created LET statement
*/
LetStatementNode *statement_create_let (void);
/*
* IF statement constructor
* returns:
* IfStatementNode* the created IF statement
*/
IfStatementNode *statement_create_if (void);
/*
* GOTO Statement Constructor
* returns:
* GotoStatementNode* the new GOTO statement
*/
GotoStatementNode *statement_create_goto (void);
/*
* GOSUB Statement Constructor
* returns:
* GosubStatementNode* the new GOSUB statement
*/
GosubStatementNode *statement_create_gosub (void);
/*
* PRINT statement constructor
* returns:
* PrintStatementNode* the created PRINT statement
*/
PrintStatementNode *statement_create_print (void);
/*
* INPUT statement constructor
* returns:
* InputStatementNode* initialised INPUT statement data
*/
InputStatementNode *statement_create_input (void);
/*
* Statement constructor
* returns:
* StatementNode* the newly-created blank statement
*/
StatementNode *statement_create (void);
/*
* Statement destructor
* params:
* StatementNode* statement the doomed statement
*/
void statement_destroy (StatementNode *statement);
/*
* Program Line Constructor
* returns:
* ProgramLineNode* the new program line
*/
ProgramLineNode *program_line_create (void);
/*
* Program Line Destructor
* params:
* ProgramLineNode* program_line the doomed program line
* params:
* ProgramLineNode* the next program line
*/
ProgramLineNode *program_line_destroy (ProgramLineNode *program_line);
/*
* Program Constructor
* returns:
* ProgramNode* the constructed program
*/
ProgramNode *program_create (void);
/*
* Program Destructor
* params:
* ProgramNode* program the doomed program
*/
void program_destroy (ProgramNode *program);
#endif

View File

@@ -0,0 +1,98 @@
/*
* Tiny BASIC
* Token Handling Header
*
* Copyright (C) Damian Walker 2019
* Created: 15-Aug-2019
*/
#ifndef __TOKEN_H__
#define __TOKEN_H__
/*
* Type Declarations
*/
/* token classes */
typedef enum
{
TOKEN_NONE, /* no token has yet been identified */
TOKEN_EOF, /* end of file */
TOKEN_EOL, /* end of line */
TOKEN_WORD, /* an identifier or keyword - token to be removed */
TOKEN_NUMBER, /* a numeric constant */
TOKEN_SYMBOL, /* a legal symbol - token to be removed */
TOKEN_STRING, /* a string constant */
TOKEN_LET, /* the LET keyword */
TOKEN_IF, /* the IF keyword */
TOKEN_THEN, /* the THEN keyword */
TOKEN_GOTO, /* the GOTO keyword */
TOKEN_GOSUB, /* the GOSUB keyword */
TOKEN_RETURN, /* the RETURN keyword */
TOKEN_END, /* the END keyword */
TOKEN_PRINT, /* the PRINT keyword */
TOKEN_INPUT, /* the INPUT keyword */
TOKEN_REM, /* the REM keyword */
TOKEN_VARIABLE, /* a single letter A..Z */
TOKEN_PLUS, /* addition or unary positive */
TOKEN_MINUS, /* subtraction or unary negative */
TOKEN_MULTIPLY, /* multiplication */
TOKEN_DIVIDE, /* division */
TOKEN_LEFT_PARENTHESIS, /* open parenthesis */
TOKEN_RIGHT_PARENTHESIS, /* close parenthesis */
TOKEN_EQUAL, /* = */
TOKEN_UNEQUAL, /* <> or >< */
TOKEN_LESSTHAN, /* < */
TOKEN_LESSOREQUAL, /* <= */
TOKEN_GREATERTHAN, /* > */
TOKEN_GREATEROREQUAL, /* >= */
TOKEN_COMMA, /* comma separator */
TOKEN_ILLEGAL /* unrecognised characters */
} TokenClass;
/* token structure */
typedef struct token Token;
typedef struct token
{
void *data; /* private data */
TokenClass (*get_class) (Token *);
int (*get_line) (Token *);
int (*get_pos) (Token *);
char *(*get_content) (Token *);
void (*set_class) (Token *, TokenClass);
void (*set_line_pos) (Token *, int, int);
void (*set_content) (Token *, char *);
void (*initialise) (Token *, TokenClass, int, int, char *);
void (*destroy) (Token *); /* destructor */
} Token;
/*
* Function Declarations
*/
/*
* Token constructor without values to initialise
* returns:
* Token* the created token
*/
Token *new_Token (void);
/*
* Token constructor with values to initialise
* params:
* TokenClass class class of token to initialise
* int line line on which the token occurred
* int pos character position on which the token occurred
* char* content the textual content of the token
* returns:
* Token* the created token
*/
Token *new_Token_init (TokenClass class, int line, int pos, char *content);
#endif

View File

@@ -0,0 +1,48 @@
/*
* Tiny BASIC
* Tokenisation Header
*
* Copyright (C) Damian Walker 2019
* Created: 04-Aug-2019
*/
#ifndef __TOKENISER_H__
#define __TOKENISER_H__
/* pre-requisite headers */
#include "token.h"
/*
* Structure Defnitions
*/
/* Token stream */
typedef struct token_stream TokenStream;
typedef struct token_stream {
void *data; /* private data */
Token *(*next) (TokenStream *);
int (*get_line) (TokenStream *);
void (*destroy) (TokenStream *);
} TokenStream;
/*
* Constructor Declarations
*/
/*
* Constructor for TokenStream
* params:
* FILE* input Input file
* returns:
* TokenStream* The new token stream
*/
TokenStream *new_TokenStream (FILE *input);
#endif