From a3e44d6a58655172be16b73a466ccc3b2f945b1a Mon Sep 17 00:00:00 2001 From: SkrinVex Date: Thu, 25 Dec 2025 12:36:05 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script.fox | 14 +++++++ src/AST.h | 76 +++++++++++++++++++++++++++++++++ src/Lexer.cpp | 63 ++++++++++++++++++++++++++++ src/Lexer.h | 14 +++++++ src/Parser.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Parser.h | 21 ++++++++++ src/Token.h | 19 +++++++++ src/foxlang | Bin 0 -> 128336 bytes src/main.cpp | 29 +++++++++++++ test.fox | 6 +++ 10 files changed, 353 insertions(+) create mode 100644 script.fox create mode 100644 src/AST.h create mode 100644 src/Lexer.cpp create mode 100644 src/Lexer.h create mode 100644 src/Parser.cpp create mode 100644 src/Parser.h create mode 100644 src/Token.h create mode 100755 src/foxlang create mode 100644 src/main.cpp create mode 100644 test.fox diff --git a/script.fox b/script.fox new file mode 100644 index 0000000..08fe969 --- /dev/null +++ b/script.fox @@ -0,0 +1,14 @@ +{ + print("=== Welcome to FoxLang ==="); + + print("Math test:"); + print(20 + 30 * 2); + + print("Type something:"); + print(input()); + + { + print("I am inside a block!"); + } + +} diff --git a/src/AST.h b/src/AST.h new file mode 100644 index 0000000..01bb260 --- /dev/null +++ b/src/AST.h @@ -0,0 +1,76 @@ +#pragma once +#include +#include +#include +#include +#include + +// Хелпер для красивого вывода чисел +static std::string formatNumber(double val) { + std::string s = std::to_string(val); + // Удаляем лишние нули и точку, если число целое + s.erase(s.find_last_not_of('0') + 1, std::string::npos); + if (s.back() == '.') s.pop_back(); + return s; +} + +struct Node { + virtual ~Node() = default; + virtual std::string eval() = 0; +}; + +struct NumberNode : Node { + std::string val; + NumberNode(std::string v) : val(v) {} + std::string eval() override { return val; } +}; + +struct BinOpNode : Node { + char op; + std::unique_ptr left, right; + BinOpNode(char o, std::unique_ptr l, std::unique_ptr r) + : op(o), left(std::move(l)), right(std::move(r)) {} + + std::string eval() override { + double l = std::stod(left->eval()); + double r = std::stod(right->eval()); + double res = 0; + if (op == '+') res = l + r; + else if (op == '-') res = l - r; + else if (op == '*') res = l * r; + else if (op == '/') res = (r != 0) ? l / r : 0; + return formatNumber(res); + } +}; + +struct RoundNode : Node { + std::unique_ptr expr; + RoundNode(std::unique_ptr e) : expr(std::move(e)) {} + std::string eval() override { + double val = std::stod(expr->eval()); + return formatNumber(std::round(val)); + } +}; + +struct RandomNode : Node { + std::string eval() override { + return std::to_string(rand() % 100); // Случайное от 0 до 99 + } +}; + +struct PrintNode : Node { + std::unique_ptr expr; + PrintNode(std::unique_ptr e) : expr(std::move(e)) {} + std::string eval() override { + std::cout << expr->eval() << std::endl; + return ""; + } +}; + +struct InputNode : Node { + std::string eval() override { + std::string buffer; + std::getline(std::cin, buffer); + return buffer; + } +}; diff --git a/src/Lexer.cpp b/src/Lexer.cpp new file mode 100644 index 0000000..049b842 --- /dev/null +++ b/src/Lexer.cpp @@ -0,0 +1,63 @@ +#include "Lexer.h" +#include +#include + +Lexer::Lexer(std::string src) : source(src) {} + +std::vector Lexer::tokenize() { + std::vector tokens; + while (pos < source.length()) { + char current = source[pos]; + + if (isspace(current)) { + if (current == '\n') line++; + pos++; + } + else if (isdigit(current)) { + std::string num; + while (pos < source.length() && isdigit(source[pos])) num += source[pos++]; + // Точка для дробных чисел (например, 3.14) + if (pos < source.length() && source[pos] == '.') { + num += source[pos++]; + while (pos < source.length() && isdigit(source[pos])) num += source[pos++]; + } + tokens.push_back({TokenType::NUMBER, num, line}); + } + else if (current == '"') { + pos++; std::string str; + while (pos < source.length() && source[pos] != '"') str += source[pos++]; + pos++; + tokens.push_back({TokenType::STRING, str, line}); + } + else if (isalpha(current)) { + std::string id; + while (pos < source.length() && isalpha(source[pos])) id += source[pos++]; + + if (id == "print") tokens.push_back({TokenType::PRINT, id, line}); + else if (id == "input") tokens.push_back({TokenType::INPUT, id, line}); + else if (id == "round") tokens.push_back({TokenType::ROUND, id, line}); + else if (id == "random") tokens.push_back({TokenType::RANDOM, id, line}); + else if (id == "fox") tokens.push_back({TokenType::FOX, id, line}); + else tokens.push_back({TokenType::IDENTIFIER, id, line}); // Неизвестное слово + } + else { + switch (current) { + case '+': tokens.push_back({TokenType::PLUS, "+", line}); break; + case '-': tokens.push_back({TokenType::MINUS, "-", line}); break; + case '*': tokens.push_back({TokenType::STAR, "*", line}); break; + case '/': tokens.push_back({TokenType::SLASH, "/", line}); break; + case '(': tokens.push_back({TokenType::LPAREN, "(", line}); break; + case ')': tokens.push_back({TokenType::RPAREN, ")", line}); break; + case '{': tokens.push_back({TokenType::LBRACE, "{", line}); break; + case '}': tokens.push_back({TokenType::RBRACE, "}", line}); break; + case ';': tokens.push_back({TokenType::SEMICOLON, ";", line}); break; + default: + std::cerr << "Lexer Error: Unknown char '" << current << "' at line " << line << std::endl; + exit(1); + } + pos++; + } + } + tokens.push_back({TokenType::END, "", line}); + return tokens; +} diff --git a/src/Lexer.h b/src/Lexer.h new file mode 100644 index 0000000..0881d92 --- /dev/null +++ b/src/Lexer.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include "Token.h" + +class Lexer { + std::string source; + size_t pos = 0; + int line = 1; + +public: + Lexer(std::string src); + std::vector tokenize(); +}; diff --git a/src/Parser.cpp b/src/Parser.cpp new file mode 100644 index 0000000..b507e5d --- /dev/null +++ b/src/Parser.cpp @@ -0,0 +1,111 @@ +#include "Parser.h" +#include + +Parser::Parser(std::vector t) : tokens(t) {} + +Token Parser::consume(TokenType type) { + if (tokens[pos].type == type) return tokens[pos++]; + std::cerr << "Syntax Error: Expected token type " << (int)type + << " but found '" << tokens[pos].value + << "' on line " << tokens[pos].line << std::endl; + exit(1); +} + +// Выражения (возвращают значение) +std::unique_ptr Parser::primary() { + if (tokens[pos].type == TokenType::NUMBER) return std::make_unique(consume(TokenType::NUMBER).value); + if (tokens[pos].type == TokenType::STRING) return std::make_unique(consume(TokenType::STRING).value); + + // input() + if (tokens[pos].type == TokenType::INPUT) { + consume(TokenType::INPUT); consume(TokenType::LPAREN); consume(TokenType::RPAREN); + return std::make_unique(); + } + + // round( expr ) + if (tokens[pos].type == TokenType::ROUND) { + consume(TokenType::ROUND); + consume(TokenType::LPAREN); + auto node = expression(); + consume(TokenType::RPAREN); + return std::make_unique(std::move(node)); + } + + // random() + if (tokens[pos].type == TokenType::RANDOM) { + consume(TokenType::RANDOM); consume(TokenType::LPAREN); consume(TokenType::RPAREN); + return std::make_unique(); + } + + if (tokens[pos].type == TokenType::LPAREN) { + consume(TokenType::LPAREN); + auto node = expression(); + consume(TokenType::RPAREN); + return node; + } + + std::cerr << "Error: Unexpected token '" << tokens[pos].value << "' in expression at line " << tokens[pos].line << std::endl; + exit(1); +} + +std::unique_ptr Parser::multiplication() { + auto node = primary(); + while (tokens[pos].type == TokenType::STAR || tokens[pos].type == TokenType::SLASH) { + char op = tokens[pos].value[0]; pos++; + node = std::make_unique(op, std::move(node), primary()); + } + return node; +} + +std::unique_ptr Parser::expression() { + auto node = multiplication(); + while (tokens[pos].type == TokenType::PLUS || tokens[pos].type == TokenType::MINUS) { + char op = tokens[pos].value[0]; pos++; + node = std::make_unique(op, std::move(node), multiplication()); + } + return node; +} + +// Блоки кода +void Parser::block() { + consume(TokenType::LBRACE); + while (tokens[pos].type != TokenType::RBRACE && tokens[pos].type != TokenType::END) { + statement(); + } + consume(TokenType::RBRACE); +} + +// Инструкции (заканчиваются ;) +void Parser::statement() { + if (tokens[pos].type == TokenType::PRINT) { + consume(TokenType::PRINT); + consume(TokenType::LPAREN); + auto expr = expression(); + consume(TokenType::RPAREN); + consume(TokenType::SEMICOLON); + auto pNode = std::make_unique(std::move(expr)); + pNode->eval(); + } + else if (tokens[pos].type == TokenType::FOX) { + consume(TokenType::FOX); + consume(TokenType::LPAREN); // fox ( + consume(TokenType::RPAREN); // ) + consume(TokenType::SEMICOLON); // ; + std::cout << " (\\_/) \n (o.o) \n (> <) OFOX!" << std::endl; + } + else if (tokens[pos].type == TokenType::LBRACE) { + block(); + } + else { + // ОБРАБОТКА ОШИБОК: Если встретили слово, которое не является командой + std::cerr << "Runtime Error: Unknown command or function '" << tokens[pos].value + << "' at line " << tokens[pos].line << std::endl; + exit(1); + } +} + +void Parser::run() { + while (tokens[pos].type != TokenType::END) { + statement(); + } +} diff --git a/src/Parser.h b/src/Parser.h new file mode 100644 index 0000000..0655779 --- /dev/null +++ b/src/Parser.h @@ -0,0 +1,21 @@ +#pragma once +#include "Token.h" +#include "AST.h" +#include +#include + +class Parser { + std::vector tokens; + size_t pos = 0; + + Token consume(TokenType type); + std::unique_ptr primary(); + std::unique_ptr multiplication(); + std::unique_ptr expression(); + void statement(); // Обработка отдельной команды с точкой с запятой + void block(); // Обработка блока { ... } + +public: + Parser(std::vector t); + void run(); +}; diff --git a/src/Token.h b/src/Token.h new file mode 100644 index 0000000..9934423 --- /dev/null +++ b/src/Token.h @@ -0,0 +1,19 @@ +#pragma once +#include + +enum class TokenType { + NUMBER, STRING, + PLUS, MINUS, STAR, SLASH, + LPAREN, RPAREN, + LBRACE, RBRACE, SEMICOLON, + PRINT, INPUT, + ROUND, FOX, RANDOM, // Новые команды + IDENTIFIER, // Для неизвестных слов + END, ERROR +}; + +struct Token { + TokenType type; + std::string value; + int line; +}; diff --git a/src/foxlang b/src/foxlang new file mode 100755 index 0000000000000000000000000000000000000000..1e8d6e759812ebf1883b5f5a54ce356a6a8ea5f5 GIT binary patch literal 128336 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

e-)Z>&JX4Swg$6&U)$5BDC3rRU;m6c4oFdna(f` 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 By{`ZO literal 0 HcmV?d00001 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..27ea438 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include "Lexer.h" +#include "Parser.h" + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::cout << "Usage: foxlang " << std::endl; + return 1; + } + + std::ifstream file(argv[1]); + if (!file.is_open()) { + std::cerr << "Error: File not found!" << std::endl; + return 1; + } + + std::stringstream buffer; + buffer << file.rdbuf(); + + Lexer lexer(buffer.str()); + auto tokens = lexer.tokenize(); + + Parser parser(tokens); + parser.run(); + + return 0; +} diff --git a/test.fox b/test.fox new file mode 100644 index 0000000..0e9e967 --- /dev/null +++ b/test.fox @@ -0,0 +1,6 @@ +{ + + print("Добро пожаловать в FoxLang"); + print(input() + input()); + +}