diff --git a/src/builtin-functions.c b/src/builtin-functions.c index adb3f0e..6194465 100644 --- a/src/builtin-functions.c +++ b/src/builtin-functions.c @@ -72,6 +72,8 @@ int BuiltinFunction_Plus(CallFrame* top_frame) case VALUETYPE_BOOLEAN: result.get.boolean = v2.get.boolean + v1.get.boolean; break; + case VALUETYPE_OBJECT: + return EXIT_FAILURE; } top_frame->instruction_pointer++; @@ -105,6 +107,8 @@ int BuiltinFunction_Multiply(CallFrame* top_frame) case VALUETYPE_BOOLEAN: result.get.boolean = v2.get.boolean * v1.get.boolean; break; + case VALUETYPE_OBJECT: + return EXIT_FAILURE; } top_frame->instruction_pointer++; @@ -138,6 +142,8 @@ int BuiltinFunction_Minus(CallFrame* top_frame) case VALUETYPE_BOOLEAN: result.get.boolean = v2.get.boolean - v1.get.boolean; break; + case VALUETYPE_OBJECT: + return EXIT_FAILURE; } top_frame->instruction_pointer++; @@ -167,6 +173,17 @@ int BuiltinFunction_PrintLine(CallFrame* top_frame) printf("false\n"); } break; + case VALUETYPE_OBJECT: + if (v1.get.object != NULL) { + StringView type_name_view = v1.get.object->type->name; + char type_name[type_name_view.length]; + type_name[type_name_view.length] = '\0'; + StringView_Paste(type_name, type_name_view); + printf("object (%s) at %p\n", type_name, (void*) v1.get.object); + break; + } else { + puts("null"); + } } return EXIT_SUCCESS; diff --git a/src/callframe.h b/src/callframe.h index 9f18051..37b023a 100644 --- a/src/callframe.h +++ b/src/callframe.h @@ -23,9 +23,9 @@ #include "function.h" #include "variable.h" #include "value.h" -#include "dynamicarray/dynamicarray.h" -#include "StringView/StringView.h" -#include "Scratchpad/Scratchpad.h" +#include "../submodules/utilitiec/src/dynamicarray/dynamicarray.h" +#include "../submodules/utilitiec/src/StringView/StringView.h" +#include "../submodules/utilitiec/src/Scratchpad/Scratchpad.h" typedef struct CallFrame_s { size_t instruction_pointer; @@ -56,4 +56,4 @@ bool CallFrame_IsReturningBody(CallFrame* frame); -#endif \ No newline at end of file +#endif diff --git a/src/function.h b/src/function.h index 1022709..9b1ae9f 100644 --- a/src/function.h +++ b/src/function.h @@ -21,7 +21,7 @@ #define FLUP_FUNCTION_H #include -#include "StringView/StringView.h" +#include "../submodules/utilitiec/src/StringView/StringView.h" typedef struct FlupFunctionAlternative_s { size_t condition_token_start; @@ -45,4 +45,4 @@ typedef struct FlupFunction_s { struct FlupFunction_s* next; } FlupFunction; -#endif \ No newline at end of file +#endif diff --git a/src/interpreter.c b/src/interpreter.c index d8c9d01..f8fc08f 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -478,6 +478,10 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token) break; } + case TOKENTYPE_COMMENT: + top_frame->instruction_pointer++; + break; + case TOKENTYPE_PIPE: case TOKENTYPE_SEMICOLON: case TOKENTYPE_LEFT_BRACE: @@ -494,6 +498,7 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token) case TOKENTYPE_COMMA: case TOKENTYPE_LEFT_PAREN: case TOKENTYPE_RIGHT_PAREN: + case TOKENTYPE_STRING: fprintf(stderr, "Unexpected token with type: %s, continuing with next token...\n", TokenType_ToString(t->type)); top_frame->instruction_pointer++; break; diff --git a/src/object-type.h b/src/object-type.h new file mode 100644 index 0000000..edc0350 --- /dev/null +++ b/src/object-type.h @@ -0,0 +1,41 @@ + + +/* + * 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. + */ +#ifndef FLUP_OBJECTTYPE_H +#define FLUP_OBJECTTYPE_H + +#include "../submodules/utilitiec/src/hashmap/hashmap.h" +#include "../submodules/utilitiec/src/StringView/StringView.h" + +#include "value.h" + +typedef struct ObjectTypeAttribute_s { + StringView name; + enum ValueType type; + uint32_t index; +} ObjectTypeAttribute; + +typedef struct ObjectType_s { + hashmap_t attributes; // map of (char* name) -> (ObjectTypeAttribute entry) + StringView name; +} ObjectType; + +#endif diff --git a/src/object.h b/src/object.h new file mode 100644 index 0000000..9c724db --- /dev/null +++ b/src/object.h @@ -0,0 +1,31 @@ +/* + * 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. + */ +#ifndef FLUP_OBJECT_H +#define FLUP_OBJECT_H + +#include "object-type.h" + +struct Object_s { + struct Object_s* next; // linked list of all objects + ObjectType* type; + union ValueContent attributes[]; +}; + +#endif diff --git a/src/tokenizer.c b/src/tokenizer.c index 8a920f3..3a95999 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -94,6 +94,16 @@ static Token _Tokenizer_IdentifierToken(StringView* source) }; } +static bool _Tokenizer_ContinueCommentFunction(char c) +{ + return c != '\n'; +} + +static bool _Tokenizer_ContinueStringFunction(char c) +{ + return c != '"'; +} + static Token _Tokenizer_SimpleToken(StringView* source) { const char* literal_table[] = { "{", "}", "&", ":", "+", "->", "-", "*", "/", "|", "==", "!=", "<", "<=", ">", ">=", ",", ";", "bind", "as", "(", ")" }; @@ -135,6 +145,30 @@ static Token _Tokenizer_SimpleToken(StringView* source) return TOKEN_NONE; } +Token _Tokenizer_CommentToken(StringView* source) +{ + StringView comment = StringView_SpanWhile(source, _Tokenizer_ContinueCommentFunction); + + return (Token) { + .type = TOKENTYPE_COMMENT, + .get = { .identifier = comment }, + }; +} + +Token _Tokenizer_StringToken(StringView* source) +{ + *source = StringView_Drop(*source, 1); + StringView string = StringView_SpanWhile(source, _Tokenizer_ContinueStringFunction); + string.source--; + string.length += 2; + *source = StringView_Drop(*source, 1); + + return (Token) { + .type = TOKENTYPE_STRING, + .get = { .identifier = string }, + }; +} + Token Tokenizer_NextToken(StringView* source) { while (source->length != 0 && isspace(source->source[0])) { @@ -158,6 +192,10 @@ Token Tokenizer_NextToken(StringView* source) } else if (isalpha(source->source[0])) { // parse name return _Tokenizer_IdentifierToken(source); + } else if (StringView_StartsWith(*source, StringView_FromString("#"))) { + return _Tokenizer_CommentToken(source); + } else if (StringView_StartsWith(*source, StringView_FromString("\""))) { + return _Tokenizer_StringToken(source); } else { return (Token) {.type = TOKENTYPE_ERROR, .get = {.error = *source } }; } @@ -220,6 +258,10 @@ const char* TokenType_ToString(enum TokenType type) return "LEFT_PAREN"; case TOKENTYPE_RIGHT_PAREN: return "RIGHT_PAREN"; + case TOKENTYPE_COMMENT: + return "COMMENT"; + case TOKENTYPE_STRING: + return "STRING"; } return "INVALID"; diff --git a/src/tokenizer.h b/src/tokenizer.h index 618226f..d8ea088 100644 --- a/src/tokenizer.h +++ b/src/tokenizer.h @@ -31,6 +31,8 @@ enum TokenType { TOKENTYPE_AS, TOKENTYPE_LEFT_PAREN, TOKENTYPE_RIGHT_PAREN, + TOKENTYPE_COMMENT, + TOKENTYPE_STRING, TOKENTYPE_ERROR, }; diff --git a/src/value-content.h b/src/value-content.h new file mode 100644 index 0000000..8a71268 --- /dev/null +++ b/src/value-content.h @@ -0,0 +1,34 @@ +/* + * 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. + */ +#ifndef FLUP_VALUECONTENT_H +#define FLUP_VALUECONTENT_H + +#include + +typedef struct Object_s Object; + +union ValueContent { + int64_t i64; + double f64; + bool boolean; + Object* object; +}; + +#endif diff --git a/src/value.c b/src/value.c index 61e7835..94b4eda 100644 --- a/src/value.c +++ b/src/value.c @@ -29,6 +29,8 @@ bool Value_IsTruthy(Value* v) return v->get.f64 != 0.0; case VALUETYPE_BOOLEAN: return v->get.boolean; + case VALUETYPE_OBJECT: + return v->get.object != NULL; } return false; @@ -43,7 +45,9 @@ bool Value_Equal(Value* v1, Value* v2) case VALUETYPE_DOUBLE: return v1->get.f64 == v2->get.f64; case VALUETYPE_BOOLEAN: - return v1->get.boolean = v2->get.boolean; + return v1->get.boolean == v2->get.boolean; + case VALUETYPE_OBJECT: + return v1->get.object == v2->get.object; } return false; diff --git a/src/value.h b/src/value.h index 1ac4f26..e6a37fd 100644 --- a/src/value.h +++ b/src/value.h @@ -22,19 +22,18 @@ #include #include -#include "StringView/StringView.h" + +#include "../submodules/utilitiec/src/StringView/StringView.h" enum ValueType { VALUETYPE_INT64, VALUETYPE_DOUBLE, + VALUETYPE_OBJECT, VALUETYPE_BOOLEAN, }; -union ValueContent { - int64_t i64; - double f64; - bool boolean; -}; +#include "value-content.h" +#include "object.h" typedef struct Value_s { enum ValueType type; diff --git a/src/variable.h b/src/variable.h index 149e171..218c9d5 100644 --- a/src/variable.h +++ b/src/variable.h @@ -21,7 +21,7 @@ #define FLUP_VARIABLE_H #include "value.h" -#include "StringView/StringView.h" +#include "../submodules/utilitiec/src/StringView/StringView.h" typedef struct FlupVariable_s { StringView name; @@ -29,4 +29,4 @@ typedef struct FlupVariable_s { struct FlupVariable_s* next; } FlupVariable; -#endif \ No newline at end of file +#endif diff --git a/test-inputs/comment.flup b/test-inputs/comment.flup new file mode 100644 index 0000000..5f03f5c --- /dev/null +++ b/test-inputs/comment.flup @@ -0,0 +1,3 @@ +1 2 # - ++ +println diff --git a/test-inputs/string.flup b/test-inputs/string.flup new file mode 100644 index 0000000..871b248 --- /dev/null +++ b/test-inputs/string.flup @@ -0,0 +1 @@ +"Hello World!" println