Skip to content
This repository was archived by the owner on Oct 12, 2026. It is now read-only.

Commit 6921657

Browse files
committed
feat: initial commit
0 parents  commit 6921657

19 files changed

Lines changed: 961 additions & 0 deletions

File tree

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea/
2+
cmake-build-debug/

‎CMakeLists.txt‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
cmake_minimum_required(VERSION 4.0)
2+
project(lambda_discipline)
3+
4+
set(CMAKE_CXX_STANDARD 20)
5+
6+
include_directories(
7+
${CMAKE_SOURCE_DIR}/include
8+
)
9+
10+
add_library(fe STATIC
11+
${CMAKE_SOURCE_DIR}/src/fe/loc.cpp
12+
${CMAKE_SOURCE_DIR}/src/fe/token.cpp
13+
${CMAKE_SOURCE_DIR}/src/fe/lexer.cpp
14+
${CMAKE_SOURCE_DIR}/src/fe/ast.cpp
15+
${CMAKE_SOURCE_DIR}/src/fe/parser.cpp
16+
)
17+
18+
add_library(intp STATIC
19+
${CMAKE_SOURCE_DIR}/src/intp/types.cpp
20+
)
21+
22+
add_executable(lambda_discipline ${CMAKE_SOURCE_DIR}/src/main.cpp)
23+
target_link_libraries(lambda_discipline PRIVATE fe intp)
24+
25+
# TODO: Add build tests
26+
# EXAMPLE: add_executable(lexer_test ../tests/lexer_test.cc)
27+
# target_link_libraries(lexer_test PRIVATE fe)

‎README.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Getting Started
2+
3+
```bash
4+
mkdir build
5+
cd build
6+
cmake ..
7+
make
8+
```
9+
10+
> TODO: Add build instructions for Windows as well.

‎examples/hello_world.lbd‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(print "Hello World\n")

‎examples/std.lbd‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- booleans and conditions
2+
true: Bool = \x: Any. \y: Any. x
3+
false: Bool = \x: Any. \y: Any. y
4+
5+
ifthen: Any = \condition: Any.
6+
\then_clause: Any. \else_clause: Any.
7+
(condition then_clause else_clause)
8+
9+
-- pairs
10+
pair: Any = \x: Any. \y: Any. \fn: Any. (fn x y)
11+
12+
first: Any = \x: Any. \y: Any. x
13+
second: Any = \x: Any. \y: Any. y
14+
15+
-- misc
16+
float_eq: Float -> Float -> Bool = \x: Float. \y: Float.
17+
(ifzero (cmp x y) true false)

‎include/lbd/error.h‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <cassert>
4+
5+
template<typename>
6+
inline constexpr bool always_false_v = false;
7+
8+
#define STATIC_ASSERT(VAL, MSG) \
9+
static_assert(VAL, __FILE__ ":" STRINGIFY(__LINE__) ": " MSG)
10+
11+
#define STATIC_ASSERT_UNREACHABLE_T(TYPE, MSG) STATIC_ASSERT((always_false_v<TYPE>), MSG)
12+
#define STATIC_ASSERT_UNREACHABLE(MSG) STATIC_ASSERT(false, MSG)
13+
14+
#define STRINGIFY2(x) #x
15+
#define STRINGIFY(x) STRINGIFY2(x)
16+
17+
#if defined(_MSC_VER)
18+
#define UNREACHABLE_OP __assume(false)
19+
#elif defined(__clang__) || defined(__GNUC__)
20+
#define UNREACHABLE_OP __builtin_unreachable()
21+
#elif __cplusplus >= 202300L
22+
#include <utility>
23+
#define UNREACHABLE_OP std::unreachable()
24+
#else
25+
#define UNREACHABLE_OP ((void)0)
26+
#endif
27+
28+
#define UNREACHABLE(MSG) (assert(false && (MSG)), UNREACHABLE_OP)

‎include/lbd/fe/ast.h‎

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <lbd/fe/loc.h>
5+
#include <lbd/intp/types.h>
6+
#include <string>
7+
#include <variant>
8+
#include <vector>
9+
10+
namespace fe::ast {
11+
struct IdenAstNode {
12+
std::string value;
13+
loc::Loc loc;
14+
15+
friend std::ostream &operator<<(std::ostream &os, const IdenAstNode &node);
16+
};
17+
18+
struct StringAstNode {
19+
std::string value;
20+
loc::Loc loc;
21+
22+
friend std::ostream &operator<<(std::ostream &os, const StringAstNode &node);
23+
};
24+
25+
struct FloatAstNode {
26+
double value;
27+
loc::Loc loc;
28+
29+
friend std::ostream &operator<<(std::ostream &os, const FloatAstNode &node);
30+
};
31+
32+
struct Expression;
33+
34+
struct LambdaExpression {
35+
IdenAstNode arg;
36+
intp::types::Type arg_type;
37+
std::unique_ptr<Expression> expr;
38+
loc::Loc loc;
39+
intp::types::CompoundType lmd_expr_type; // Lambda Expression Type
40+
41+
void print(std::ostream &os, size_t indent) const;
42+
43+
friend std::ostream &operator<<(std::ostream &os, const LambdaExpression &l_expr);
44+
};
45+
46+
struct FunctionApplication {
47+
IdenAstNode fn_name;
48+
std::vector<std::unique_ptr<Expression> > args;
49+
loc::Loc loc;
50+
51+
void print(std::ostream &os, size_t indent) const;
52+
53+
friend std::ostream &operator<<(std::ostream &os, const FunctionApplication &fn_apl);
54+
};
55+
56+
struct Expression {
57+
using ExpressionVariant = std::variant<
58+
IdenAstNode,
59+
StringAstNode,
60+
FloatAstNode,
61+
LambdaExpression,
62+
FunctionApplication
63+
>;
64+
65+
ExpressionVariant value;
66+
67+
explicit Expression(IdenAstNode value);
68+
69+
explicit Expression(StringAstNode value);
70+
71+
explicit Expression(FloatAstNode value);
72+
73+
explicit Expression(LambdaExpression value);
74+
75+
explicit Expression(FunctionApplication value);
76+
77+
void print(std::ostream &os, size_t indent) const;
78+
79+
friend std::ostream &operator<<(std::ostream &os, const Expression &expr);
80+
81+
[[nodiscard]] loc::Loc get_loc() const;
82+
83+
Expression(const Expression &) = delete;
84+
85+
Expression &operator=(const Expression &) = delete;
86+
87+
Expression(Expression &&) noexcept = default;
88+
89+
Expression &operator=(Expression &&) noexcept = default;
90+
};
91+
92+
struct DefAstNode {
93+
IdenAstNode def_name;
94+
intp::types::Type typ;
95+
Expression expr;
96+
loc::Loc loc;
97+
98+
void print(std::ostream &os, size_t indent) const;
99+
100+
friend std::ostream &operator<<(std::ostream &os, const DefAstNode &node);
101+
};
102+
103+
struct AstNode {
104+
using NodeVariant = std::variant<Expression, DefAstNode>;
105+
106+
NodeVariant value;
107+
108+
void print(std::ostream &os, size_t indent) const;
109+
110+
friend std::ostream &operator<<(std::ostream &os, const AstNode &node);
111+
};
112+
113+
struct Program {
114+
std::vector<AstNode> nodes;
115+
116+
friend std::ostream &operator<<(std::ostream &os, const Program &p);
117+
};
118+
}

‎include/lbd/fe/lexer.h‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include <lbd/fe/loc.h>
4+
#include <lbd/fe/token.h>
5+
#include <string>
6+
#include <vector>
7+
8+
namespace fe::lexer {
9+
struct Lexer {
10+
std::string source;
11+
size_t pos = 0;
12+
size_t row = 1;
13+
size_t col = 1;
14+
std::string filepath;
15+
16+
explicit Lexer(const std::string &filepath);
17+
18+
token::Token next_token();
19+
20+
std::vector<token::Token> lex_all();
21+
22+
private:
23+
[[nodiscard]] char peek() const;
24+
25+
char get();
26+
27+
[[nodiscard]] bool is_eof() const;
28+
29+
[[nodiscard]] loc::Loc get_cur_loc() const;
30+
};
31+
}

‎include/lbd/fe/loc.h‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
6+
namespace fe::loc {
7+
struct Loc {
8+
size_t row;
9+
size_t col;
10+
std::string filepath;
11+
12+
Loc(size_t row, size_t col, std::string filepath);
13+
14+
friend std::ostream &operator<<(std::ostream &os, const Loc &loc);
15+
};
16+
}

‎include/lbd/fe/parser.h‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <lbd/fe/ast.h>
4+
#include <lbd/fe/token.h>
5+
#include <lbd/intp/types.h>
6+
#include <vector>
7+
8+
namespace fe::parser {
9+
struct Parser {
10+
ast::Program program;
11+
12+
explicit Parser(const std::vector<token::Token> &tokens);
13+
14+
private:
15+
// TODO: Add checks for T to be a variant of fe::token::TokenType
16+
template<typename T>
17+
static void assert_token(const std::vector<token::Token> &tokens, size_t &i);
18+
19+
template<typename T>
20+
static void assert_n_eat(const std::vector<token::Token> &tokens, size_t &i);
21+
22+
static ast::IdenAstNode eat_iden(const std::vector<token::Token> &tokens, size_t &i);
23+
24+
static intp::types::PrimitiveType eat_primitive_type_name(const std::vector<token::Token> &tokens, size_t &i);
25+
26+
static intp::types::Type parse_type(const std::vector<token::Token> &tokens, size_t &i);
27+
28+
static ast::Expression parse_expression(const std::vector<token::Token> &tokens, size_t &i);
29+
30+
static ast::LambdaExpression parse_lambda_expression(const std::vector<token::Token> &tokens, size_t &i);
31+
32+
static ast::FunctionApplication parse_function_application(const std::vector<token::Token> &tokens, size_t &i);
33+
34+
static ast::DefAstNode parse_def_ast_node(const std::vector<token::Token> &tokens, size_t &i);
35+
36+
static std::vector<ast::AstNode> build_ast(const std::vector<token::Token> &tokens, size_t &i);
37+
};
38+
}

0 commit comments

Comments
 (0)