feat: initial commit

This commit is contained in:
lisk77 2025-06-30 19:43:09 +02:00
commit 0dd91da74f
17 changed files with 683 additions and 0 deletions

39
include/ast.hpp Normal file
View file

@ -0,0 +1,39 @@
#ifndef AST_HPP
#define AST_HPP
#include <memory>
#include <string>
// ast stuff lul
struct Expr {
virtual ~Expr() = default;
};
// represents a simple symbol like "x" or even "thisIsACoolFunctionTrustme100"
// (ikik the true lambda calculus professionals would now scream at me and say
// "lambda calculus has only one letter variables!", to which id say ¯\_(ツ)_/¯
struct Variable : Expr {
std::string name;
Variable(std::string n) : name(std::move(n)) {}
};
// represents a function itself like \ x . x
struct Abstraction : Expr {
std::string param;
std::unique_ptr<Expr> body;
Abstraction(std::string p, std::unique_ptr<Expr> b) : param(std::move(p)), body(std::move(b)) {}
};
// wouldnt be turing complete if we couldnt apply to these functions innit
// (\ x . x) a would be such an application
// note that parenthesis are your savior because (\ x y . x) (\ x . x) b and
// (\ x y . x) ((\ x . x) b ) are not the same thing
struct Application : Expr {
std::unique_ptr<Expr> left, right;
Application(std::unique_ptr<Expr> l, std::unique_ptr<Expr> r) : left(std::move(l)), right(std::move(r)) {}
};
#endif // AST_HPP

14
include/evaluator.hpp Normal file
View file

@ -0,0 +1,14 @@
#ifndef EVALUATOR_HPP
#define EVALUATOR_HPP
#include "ast.hpp"
#include <unordered_map>
#include <string>
#include <stdexcept>
std::unique_ptr<Expr> normalize(const std::unique_ptr<Expr>&, const std::unordered_map<std::string, std::unique_ptr<Expr>>&);
std::unique_ptr<Expr> substitute(const std::string&, const std::unique_ptr<Expr>&, const std::unique_ptr<Expr>&);
std::unique_ptr<Expr> evaluate(const std::unique_ptr<Expr>&, const std::unordered_map<std::string, std::unique_ptr<Expr>>&);
std::unique_ptr<Expr> evaluateMain(const std::unordered_map<std::string, std::unique_ptr<Expr>>&);
#endif // EVALUATOR_HPP

18
include/lexer.hpp Normal file
View file

@ -0,0 +1,18 @@
#ifndef LEXER_HPP
#define LEXER_HPP
#include <vector>
#include <string>
#include "token.hpp"
class Lexer {
std::string src;
bool error_flag;
size_t position;
public:
Lexer(std::string);
std::vector<Token> tokenize();
};
#endif // LEXER_HPP

31
include/parser.hpp Normal file
View file

@ -0,0 +1,31 @@
#ifndef PARSER_HPP
#define PARSER_HPP
#include <vector>
#include <unordered_map>
#include "token.hpp"
#include "ast.hpp"
class Parser {
std::vector<Token> tokens;
size_t position;
bool error_flag;
std::unordered_map<std::string, std::unique_ptr<Expr>> defs;
public:
Parser(std::vector<Token>);
const std::unordered_map<std::string, std::unique_ptr<Expr>>& definitions() const;
const Token& peek() const;
const Token& get();
bool accept(TokenType t);
void expect(TokenType t);
bool tryParseDefinition();
std::unique_ptr<Expr> parseSimple();
std::unique_ptr<Expr> parseApplication();
std::unique_ptr<Expr> parseTerm();
std::unique_ptr<Expr> parse();
std::vector<std::unique_ptr<Expr>> parseProgram();
};
#endif // PARSER_HPP

31
include/token.hpp Normal file
View file

@ -0,0 +1,31 @@
#ifndef TOKEN_H
#define TOKEN_H
#include <stdint.h>
#include <stdlib.h>
#include <string>
typedef enum {
ERROR,
EOL,
EOC,
LAMBDA,
DOT,
LPAREN,
RPAREN,
VARIABLE,
EQUALS
} TokenType;
typedef struct {
TokenType type;
std::string lexeme;
size_t start;
size_t end;
} Token;
void print_lexeme(Token);
std::string display_tokentype(TokenType);
void print_token(Token);
#endif // TOKEN_H