Initial commit

This commit is contained in:
VegOwOtenks 2024-09-24 15:34:51 +02:00
parent 6fabc85fab
commit 13495d95e7
7 changed files with 233 additions and 0 deletions

BIN
bin/flup Executable file

Binary file not shown.

1
include/utilitiec Symbolic link
View file

@ -0,0 +1 @@
/home/vego/Git/utilitiec/src/

1
lib/utilitiec Symbolic link
View file

@ -0,0 +1 @@
/home/vego/Git/utilitiec/build/lib/

1
make.sh Normal file
View 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

82
src/main.c Normal file
View file

@ -0,0 +1,82 @@
/*
* 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"
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);
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;
}
char* script_string = load_file_string(script_file.content);
if (script_string == NULL) return 1;
puts(script_string);
return EXIT_SUCCESS;
}

116
src/tokenizer.c Normal file
View file

@ -0,0 +1,116 @@
#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,
}
};
}
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;
}
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 } };
}
}

32
src/tokenizer.h Normal file
View file

@ -0,0 +1,32 @@
#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_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);
#endif //header guard