Compare commits
4 commits
1b6507847a
...
b5912b95f7
Author | SHA1 | Date | |
---|---|---|---|
b5912b95f7 | |||
371eca6269 | |||
13495d95e7 | |||
6fabc85fab |
11 changed files with 530 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
bin/
|
1
include/utilitiec
Symbolic link
1
include/utilitiec
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/vego/Git/utilitiec/src/
|
1
lib/utilitiec
Symbolic link
1
lib/utilitiec
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/vego/Git/utilitiec/build/lib/
|
1
make.sh
Normal file
1
make.sh
Normal file
|
@ -0,0 +1 @@
|
||||||
|
gcc `find src/ -name '*.c'` lib/utilitiec/libargumentc.a lib/utilitiec/libdynamicarray.a lib/utilitiec/libpointers.a lib/utilitiec/liballocator-interface.a lib/utilitiec/libStringView.a -lm -ggdb -o bin/flup
|
50
src/interpreter.c
Normal file
50
src/interpreter.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#include "interpreter.h"
|
||||||
|
|
||||||
|
static int CallFrame_Create(CallFrame* self, FlupFunctionAlternative* f)
|
||||||
|
{
|
||||||
|
if (DynamicArray_Create(&self->stack, sizeof(Value), 8, NULL)) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
self->function = f;
|
||||||
|
self->instruction_pointer = f->body_token_start;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FlupFunctionAlternative* FlupFunctionAlternative_Malloc(size_t condition_token_start, size_t condition_token_end, size_t body_token_start, size_t body_token_end)
|
||||||
|
{
|
||||||
|
FlupFunctionAlternative* a = malloc(sizeof(FlupFunctionAlternative));
|
||||||
|
a->next = NULL;
|
||||||
|
a->condition_token_start = condition_token_start;
|
||||||
|
a->condition_token_end = condition_token_end;
|
||||||
|
a->body_token_start = body_token_start;
|
||||||
|
a->body_token_end = body_token_end;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Interpreter_Create(Interpreter* self, DynamicArray* tokens)
|
||||||
|
{
|
||||||
|
if (DynamicArray_Create(&self->call_frames, sizeof(CallFrame), 16, NULL)) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
self->tokens = tokens;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Interpreter_Interpret(Interpreter* self)
|
||||||
|
{
|
||||||
|
CallFrame* first_frame;
|
||||||
|
DynamicArray_AppendEmpty(&self->call_frames, (void**) &first_frame);
|
||||||
|
if (CallFrame_Create(first_frame, )) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interpreter_Destroy(Interpreter* self)
|
||||||
|
{
|
||||||
|
DynamicArray_Destroy(&self->call_frames);
|
||||||
|
}
|
59
src/interpreter.h
Normal file
59
src/interpreter.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef FLUP_INTERPRETER_H
|
||||||
|
#define FLUP_INTERPRETER_H
|
||||||
|
|
||||||
|
#include "../include/utilitiec/dynamicarray/dynamicarray.h"
|
||||||
|
|
||||||
|
#include "tokenizer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct FlupFunctionAlternative_s {
|
||||||
|
size_t condition_token_start;
|
||||||
|
size_t condition_token_end;
|
||||||
|
size_t body_token_start;
|
||||||
|
size_t body_token_end;
|
||||||
|
struct FlupFunctionAlternative_s* next;
|
||||||
|
} FlupFunctionAlternative;
|
||||||
|
|
||||||
|
typedef struct ParameterDefinition_s {
|
||||||
|
StringView name;
|
||||||
|
StringView type;
|
||||||
|
} ParameterDefinition;
|
||||||
|
|
||||||
|
typedef struct FlupFunction_s {
|
||||||
|
StringView name;
|
||||||
|
DynamicArray argument_defs; // ParameterDefinition
|
||||||
|
StringView return_type;
|
||||||
|
FlupFunctionAlternative* alternative;
|
||||||
|
} FlupFunction;
|
||||||
|
|
||||||
|
enum ValueType {
|
||||||
|
VALUETYPE_INT64,
|
||||||
|
VALUETYPE_DOUBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
union ValueContent {
|
||||||
|
int64_t i64;
|
||||||
|
double f64;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Value_s {
|
||||||
|
enum ValueType type;
|
||||||
|
union ValueContent get;
|
||||||
|
} Value;
|
||||||
|
|
||||||
|
typedef struct CallFrame_s {
|
||||||
|
size_t instruction_pointer;
|
||||||
|
FlupFunctionAlternative* function;
|
||||||
|
DynamicArray stack; // Value
|
||||||
|
} CallFrame;
|
||||||
|
|
||||||
|
typedef struct Interpreter_s {
|
||||||
|
DynamicArray* tokens;
|
||||||
|
DynamicArray call_frames; // stores CallFrame
|
||||||
|
} Interpreter;
|
||||||
|
|
||||||
|
int Interpreter_Create(Interpreter* self, DynamicArray* tokens);
|
||||||
|
int Interpreter_Interpret(Interpreter* self);
|
||||||
|
void Interpreter_Destroy(Interpreter* self);
|
||||||
|
|
||||||
|
#endif //header guard
|
120
src/main.c
Normal file
120
src/main.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* This code is part of the programming language flup
|
||||||
|
* flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later.
|
||||||
|
* Copyright (C) 2024 VegOwOtenks
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../include/utilitiec/argumentc/argumentc.h"
|
||||||
|
#include "interpreter.h"
|
||||||
|
#include "tokenizer.h"
|
||||||
|
|
||||||
|
int tokenize_all(StringView source, DynamicArray* a)
|
||||||
|
{
|
||||||
|
Token t;
|
||||||
|
while ((t = Tokenizer_NextToken(&source)).type != TOKENTYPE_NONE) {
|
||||||
|
int append_code = DynamicArray_Append(a, &t);
|
||||||
|
if (append_code) return append_code;
|
||||||
|
if (t.type == TOKENTYPE_ERROR) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* load_file_string(StringView path)
|
||||||
|
{
|
||||||
|
FILE* stream = fopen(path.source, "r");
|
||||||
|
if (stream == NULL) {
|
||||||
|
fprintf(stderr, "Fatal Error: Failed to open file at %*s\n", (int) path.length, path.source);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek(stream, 0, SEEK_END)) {
|
||||||
|
perror("fseek");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
long length = ftell(stream);
|
||||||
|
if (length == -1) {
|
||||||
|
perror("ftell");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(stream);
|
||||||
|
|
||||||
|
char* buffer = malloc(length + 1);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
fprintf(stderr, "Fatal Error: Failed to allocate %li bytes\n", length);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_read = fread(buffer, 1, length + 1, stream);
|
||||||
|
if (bytes_read != length) {
|
||||||
|
fprintf(stderr, "Fatal Error: Failed read %li bytes from script file, got only %li\n", length, bytes_read);
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char* argv [])
|
||||||
|
{
|
||||||
|
Argumentc arguments;
|
||||||
|
Argumentc_Create(&arguments, argc, argv);
|
||||||
|
|
||||||
|
Option script_file = Argumentc_PopLongArgument(&arguments, StringView_FromString("file")).argument;
|
||||||
|
if (script_file.type == OPTIONTYPE_NONE) {
|
||||||
|
fprintf(stderr, "Usage: [program] --file path/to/script_file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Argumentc_Destroy(&arguments);
|
||||||
|
|
||||||
|
char* script_string = load_file_string(script_file.content);
|
||||||
|
if (script_string == NULL) return 1;
|
||||||
|
|
||||||
|
StringView source = StringView_FromString(script_string);
|
||||||
|
DynamicArray tokens;
|
||||||
|
if (DynamicArray_Create(&tokens, sizeof(Token), 128, NULL)) {
|
||||||
|
fprintf(stderr, "Fatal Error: Failed to create dynamicarray\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenize_all(source, &tokens)) {
|
||||||
|
fprintf(stderr, "Fatal Error: Out of Memory in tokenizing\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Interpreter interpreter;
|
||||||
|
Interpreter_Create(&interpreter, &tokens);
|
||||||
|
|
||||||
|
|
||||||
|
Interpreter_Interpret(&interpreter);
|
||||||
|
|
||||||
|
Interpreter_Destroy(&interpreter);
|
||||||
|
DynamicArray_Destroy(&tokens);
|
||||||
|
|
||||||
|
free(script_string);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
209
src/tokenizer.c
Normal file
209
src/tokenizer.c
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
#include "tokenizer.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
static StringView StringViewOfNumberTillNextNonDigit(StringView* source) {
|
||||||
|
StringView stringViewOfNumber = StringView_Slice(*source, 0, 0);
|
||||||
|
while (source->length != 0 && isdigit(source->source[0])) {
|
||||||
|
*source = StringView_Drop(*source, 1);
|
||||||
|
stringViewOfNumber.length ++;
|
||||||
|
}
|
||||||
|
return stringViewOfNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t* _StringView_FoldInt64(char c, int64_t* i)
|
||||||
|
{
|
||||||
|
*i = *i * 10 + (c - '0');
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double* _StringView_FoldDouble(char c, double* d)
|
||||||
|
{
|
||||||
|
*d = *d * 10 + (c - '0');
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token _Tokenizer_ParseInt64(bool negative, StringView integerPart)
|
||||||
|
{
|
||||||
|
int64_t theInt64 = 0;
|
||||||
|
StringView_FoldLeft(integerPart, &theInt64, (StringViewFoldFunction) _StringView_FoldInt64);
|
||||||
|
|
||||||
|
return (Token) {
|
||||||
|
.type = TOKENTYPE_INTEGER,
|
||||||
|
.get = {
|
||||||
|
.integer = theInt64 * (negative ? -1 : 1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token _Tokenizer_ParseDouble(bool negative, StringView integerPart, StringView decimalPart)
|
||||||
|
{
|
||||||
|
double theDouble = 0.0;
|
||||||
|
StringView_FoldLeft(integerPart, &theDouble, (StringViewFoldFunction) _StringView_FoldDouble);
|
||||||
|
double theDecimal = 0.0;
|
||||||
|
StringView_FoldLeft(decimalPart, &theDecimal, (StringViewFoldFunction) _StringView_FoldDouble);
|
||||||
|
|
||||||
|
double result = (negative ? -1 : 1) * (theDouble + theDecimal / pow(10.0, decimalPart.length));
|
||||||
|
|
||||||
|
return (Token) {
|
||||||
|
.type = TOKENTYPE_DOUBLE,
|
||||||
|
.get = {
|
||||||
|
.decimal = result
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token _Tokenizer_NumberToken(StringView* source)
|
||||||
|
{
|
||||||
|
bool negative = false;
|
||||||
|
if (StringView_StartsWith(*source, StringView_FromString("-"))) {
|
||||||
|
negative = true;
|
||||||
|
*source = StringView_Drop(*source, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView integerPart = StringViewOfNumberTillNextNonDigit(source);
|
||||||
|
bool has_point = false;
|
||||||
|
if (source->length != 0 && source->source[0] == '.') {
|
||||||
|
*source = StringView_Drop(*source, 1);
|
||||||
|
has_point = true;
|
||||||
|
}
|
||||||
|
StringView decimalPart = StringViewOfNumberTillNextNonDigit(source);
|
||||||
|
|
||||||
|
if (has_point) {
|
||||||
|
return _Tokenizer_ParseDouble(negative, integerPart, decimalPart);
|
||||||
|
} else {
|
||||||
|
return _Tokenizer_ParseInt64(negative, integerPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _Tokenizer_IdentifierLetter(char c)
|
||||||
|
{
|
||||||
|
return isalnum(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token _Tokenizer_IdentifierToken(StringView* source)
|
||||||
|
{
|
||||||
|
StringView identifier = StringView_TakeWhile(*source, _Tokenizer_IdentifierLetter);
|
||||||
|
*source = StringView_Drop(*source, identifier.length);
|
||||||
|
|
||||||
|
return (Token) {
|
||||||
|
.type = TOKENTYPE_IDENTIFIER,
|
||||||
|
.get = {
|
||||||
|
.identifier = identifier,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token _Tokenizer_SimpleToken(StringView* source)
|
||||||
|
{
|
||||||
|
const char* literal_table[] = { "{", "}", "&", ":", "+", "->", "-", "*", "/", "|", "==", "!=", "<", "<=", ">", ">=", "," };
|
||||||
|
const enum TokenType type_table[] = {
|
||||||
|
TOKENTYPE_LEFT_BRACE,
|
||||||
|
TOKENTYPE_RIGHT_BRACE,
|
||||||
|
TOKENTYPE_AMPERSAND,
|
||||||
|
TOKENTYPE_COLON,
|
||||||
|
TOKENTYPE_PLUS,
|
||||||
|
TOKENTYPE_ARROW,
|
||||||
|
TOKENTYPE_MINUS,
|
||||||
|
TOKENTYPE_MULTIPLY,
|
||||||
|
TOKENTYPE_DIVIDE,
|
||||||
|
TOKENTYPE_PIPE,
|
||||||
|
TOKENTYPE_EQUALITY,
|
||||||
|
TOKENTYPE_INEQUALITY,
|
||||||
|
TOKENTYPE_LESSTHAN,
|
||||||
|
TOKENTYPE_LESSEQUAL,
|
||||||
|
TOKENTYPE_GREATERTHAN,
|
||||||
|
TOKENTYPE_GREATEREQUAL,
|
||||||
|
TOKENTYPE_COMMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(literal_table) / sizeof(literal_table[0]); i++) {
|
||||||
|
StringView literal_view = StringView_FromString(literal_table[i]);
|
||||||
|
if (StringView_StartsWith(*source, literal_view)) {
|
||||||
|
*source = StringView_Drop(*source, literal_view.length);
|
||||||
|
return (Token) {
|
||||||
|
.type = type_table[i],
|
||||||
|
.get = { .identifier = STRINGVIEW_NONE }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TOKEN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token Tokenizer_NextToken(StringView* source)
|
||||||
|
{
|
||||||
|
while (source->length != 0 && isspace(source->source[0])) {
|
||||||
|
0[source] = StringView_Slice(*source, 1, source->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source->length == 0) {
|
||||||
|
return TOKEN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Token simple_token = _Tokenizer_SimpleToken(source);
|
||||||
|
if (simple_token.type != TOKENTYPE_NONE) {
|
||||||
|
return simple_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdigit(source->source[0]) || StringView_StartsWith(*source, StringView_FromString("-"))) {
|
||||||
|
// parse int/double
|
||||||
|
return _Tokenizer_NumberToken(source);
|
||||||
|
} else if (isalpha(source->source[0])) {
|
||||||
|
// parse name
|
||||||
|
return _Tokenizer_IdentifierToken(source);
|
||||||
|
} else {
|
||||||
|
return (Token) {.type = TOKENTYPE_ERROR, .get = {.error = *source } };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* TokenType_ToString(enum TokenType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TOKENTYPE_NONE:
|
||||||
|
return "TOKENTYPE_NONE";
|
||||||
|
case TOKENTYPE_INTEGER:
|
||||||
|
return "TOKENTYPE_INTEGER";
|
||||||
|
case TOKENTYPE_DOUBLE:
|
||||||
|
return "TOKENTYPE_DOUBLE";
|
||||||
|
case TOKENTYPE_IDENTIFIER:
|
||||||
|
return "TOKENTYPE_IDENTIFIER";
|
||||||
|
case TOKENTYPE_LEFT_BRACE:
|
||||||
|
return "TOKENTYPE_LEFT_BRACE";
|
||||||
|
case TOKENTYPE_RIGHT_BRACE:
|
||||||
|
return "TOKENTYPE_RIGHT_BRACE";
|
||||||
|
case TOKENTYPE_AMPERSAND:
|
||||||
|
return "TOKENTYPE_AMPERSAND";
|
||||||
|
case TOKENTYPE_PLUS:
|
||||||
|
return "TOKENTYPE_PLUS";
|
||||||
|
case TOKENTYPE_MINUS:
|
||||||
|
return "TOKENTYPE_MINUS";
|
||||||
|
case TOKENTYPE_MULTIPLY:
|
||||||
|
return "TOKENTYPE_MULTIPLY";
|
||||||
|
case TOKENTYPE_DIVIDE:
|
||||||
|
return "TOKENTYPE_DIVIDE";
|
||||||
|
case TOKENTYPE_PIPE:
|
||||||
|
return "TOKENTYPE_PIPE";
|
||||||
|
case TOKENTYPE_ARROW:
|
||||||
|
return "TOKENTYPE_ARROW";
|
||||||
|
case TOKENTYPE_COLON:
|
||||||
|
return "TOKENTYPE_COLON";
|
||||||
|
case TOKENTYPE_ERROR:
|
||||||
|
return "TOKENTYPE_ERROR";
|
||||||
|
case TOKENTYPE_EQUALITY:
|
||||||
|
return "TOKENTYPE_EQUALITY";
|
||||||
|
case TOKENTYPE_INEQUALITY:
|
||||||
|
return "TOKENTYPE_INEQUALITY";
|
||||||
|
case TOKENTYPE_LESSTHAN:
|
||||||
|
return "TOKENTYPE_LESSTHAN";
|
||||||
|
case TOKENTYPE_LESSEQUAL:
|
||||||
|
return "TOKENTYPE_LESSEQUAL";
|
||||||
|
case TOKENTYPE_GREATERTHAN:
|
||||||
|
return "TOKENTYPE_GREATERTHAN";
|
||||||
|
case TOKENTYPE_GREATEREQUAL:
|
||||||
|
return "TOKENTYPE_GREATEREQUAL";
|
||||||
|
case TOKENTYPE_COMMA:
|
||||||
|
return "TOKENTYPE_COMMA";
|
||||||
|
}
|
||||||
|
}
|
50
src/tokenizer.h
Normal file
50
src/tokenizer.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef FLUP_TOKENIZER_H
|
||||||
|
#define FLUP_TOKENIZER_H
|
||||||
|
|
||||||
|
#include "../include/utilitiec/StringView/StringView.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum TokenType {
|
||||||
|
TOKENTYPE_NONE,
|
||||||
|
TOKENTYPE_INTEGER,
|
||||||
|
TOKENTYPE_DOUBLE,
|
||||||
|
TOKENTYPE_IDENTIFIER,
|
||||||
|
TOKENTYPE_LEFT_BRACE,
|
||||||
|
TOKENTYPE_RIGHT_BRACE,
|
||||||
|
TOKENTYPE_AMPERSAND,
|
||||||
|
TOKENTYPE_PLUS,
|
||||||
|
TOKENTYPE_MINUS,
|
||||||
|
TOKENTYPE_MULTIPLY,
|
||||||
|
TOKENTYPE_DIVIDE,
|
||||||
|
TOKENTYPE_PIPE,
|
||||||
|
TOKENTYPE_ARROW,
|
||||||
|
TOKENTYPE_COLON,
|
||||||
|
TOKENTYPE_EQUALITY,
|
||||||
|
TOKENTYPE_INEQUALITY,
|
||||||
|
TOKENTYPE_LESSTHAN,
|
||||||
|
TOKENTYPE_LESSEQUAL,
|
||||||
|
TOKENTYPE_GREATERTHAN,
|
||||||
|
TOKENTYPE_GREATEREQUAL,
|
||||||
|
TOKENTYPE_COMMA,
|
||||||
|
TOKENTYPE_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
union TokenContent {
|
||||||
|
StringView identifier;
|
||||||
|
StringView error;
|
||||||
|
int64_t integer;
|
||||||
|
double decimal;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Token_s {
|
||||||
|
enum TokenType type;
|
||||||
|
union TokenContent get;
|
||||||
|
} Token;
|
||||||
|
|
||||||
|
|
||||||
|
#define TOKEN_NONE ((Token) {.type = TOKENTYPE_NONE, .get = {.error = STRINGVIEW_NONE } } )
|
||||||
|
|
||||||
|
Token Tokenizer_NextToken(StringView* source);
|
||||||
|
const char* TokenType_ToString(enum TokenType type);
|
||||||
|
|
||||||
|
#endif //header guard
|
19
templates/C-Header.h
Normal file
19
templates/C-Header.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* This code is part of the programming language flup
|
||||||
|
* flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later.
|
||||||
|
* Copyright (C) 2024 VegOwOtenks
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
19
templates/C-Source.c
Normal file
19
templates/C-Source.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* This code is part of the programming language flup
|
||||||
|
* flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later.
|
||||||
|
* Copyright (C) 2024 VegOwOtenks
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
Loading…
Reference in a new issue