Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
{
"name": "SysY Compiler Dev",
"image": "maxxing/compiler-dev",

"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
"workspaceFolder": "${localWorkspaceFolder}",

"mounts": [
"source=${localEnv:HOME}/.ssh,target=/home/ubuntu/.ssh,type=bind,consistency=cached"
],

"customizations": {
"vscode": {
"extensions": [
"llvm-vs-code-extensions.vscode-clangd",
"ms-vscode.cmake-tools",
"twxs.cmake",
"daohong-emilio.yash",
"mikawi.flex-language"
"mikawi.flex-language",
"aaron-bond.better-comments",
"eamodio.gitlens"
],
"settings": {
"clangd.path": "/usr/bin/clangd-21",
Expand All @@ -35,9 +34,7 @@
}
}
},

"remoteUser": "ubuntu",

"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"username": "ubuntu",
Expand All @@ -46,13 +43,12 @@
"configureZshAsDefaultShell": true
}
},

"postCreateCommand": "sudo apt-get update && sudo apt-get install -y clangd-21",

// "postCreateCommand": "sudo apt-get update && sudo apt-get install -y clangd-21",
"postCreateCommand": "sudo apt-get update && sudo apt-get install -y clangd-21 python3-pip && sudo pip3 install ninja --break-system-packages",
"runArgs": [
"--network=host",
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
]
}
}
63 changes: 44 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
name: compiler auto test
run-name: ${{ github.actor }} is testing out compiler function 🚀

on:
push:
paths:
- 'project/**'
pull_request:
workflow_dispatch:

jobs:
build:
build_compiler:
runs-on: ubuntu-latest
container:
image: maxxing/compiler-dev
defaults:
run:
working-directory: ./project
outputs:
artifact_name: compiler-binary
steps:
- name: Check out repository code
uses: actions/checkout@v5
- name: test koopa
- uses: actions/checkout@v5

- name: Install Ninja
run: |
autotest -w debug -koopa -s lv1 .
autotest -w debug -koopa -s lv3 .
autotest -w debug -koopa -s lv4 .
autotest -w debug -koopa -s lv5 .
autotest -w debug -koopa -s lv6 .
autotest -w debug -koopa -s lv7 .
autotest -w debug -koopa -s lv8 .
- name: test riscv
apt-get update && apt-get install -y ninja-build
ninja --version

- name: Build Binary
run: make

test_compiler:
needs: build_compiler
runs-on: ubuntu-latest
container:
image: maxxing/compiler-dev
strategy:
fail-fast: false
matrix:
test_type: [koopa, riscv]
defaults:
run:
working-directory: ./project
steps:
- uses: actions/checkout@v5

- name: Install Ninja
run: |
autotest -w debug -riscv -s lv1 .
autotest -w debug -riscv -s lv3 .
autotest -w debug -riscv -s lv4 .
autotest -w debug -riscv -s lv5 .
autotest -w debug -riscv -s lv6 .
autotest -w debug -riscv -s lv7 .
apt-get update && apt-get install -y ninja-build
ninja --version

- name: Run Test
run: autotest -w debug -${{ matrix.test_type }} .
Comment on lines +19 to +53
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test_compiler job depends on build_compiler but doesn't actually use the built artifact. The build job declares an output artifact_name: compiler-binary but never uploads the artifact, and the test job doesn't download it. This means the compiler will be rebuilt in the test job. Either remove the dependency and outputs declaration from build_compiler, or implement artifact upload/download to avoid rebuilding in the test job.

Copilot uses AI. Check for mistakes.

- name: Upload Test Logs
if: failure()
uses: actions/upload-artifact@v5
with:
name: test-logs-${{ matrix.test_type }}
path: project/debug/
3 changes: 2 additions & 1 deletion project/.clang-format
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
AllowShortCaseLabelsOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
5 changes: 3 additions & 2 deletions project/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PWD := $(shell pwd)
all: build

config:
cmake -S . -B $(BUILD_DIR) -G Ninja -DCMAKE_MAKE_PROGRAM=$(PWD)/ninja
cmake -S . -B $(BUILD_DIR) -G Ninja -DCMAKE_CXX_COMPILER=clang++

build: config
cmake --build $(BUILD_DIR) -j12
Expand All @@ -28,7 +28,8 @@ run:
./cmake-build/compiler -riscv ./tests/hello.c -o ./debug/hello.asm

test:
cd cmake-build && ctest && cd ..
python3 scripts/test_runner.py koopa
python3 scripts/test_runner.py riscv

docker-build:
docker run --rm \
Expand Down
4 changes: 2 additions & 2 deletions project/include/backend/backend.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ private:
*/
auto visit(const koopa_raw_return_t &ret) -> void;
auto visit(const koopa_raw_binary_t &binary) -> void;
auto visit(const koopa_raw_integer_t &integer) -> void;
auto visit(const koopa_raw_jump_t &jump) -> void;
auto visit(const koopa_raw_branch_t &branch) -> void;
auto visit(const koopa_raw_load_t &load) -> void;
auto visit(const koopa_raw_store_t &store) -> void;
auto visit(const koopa_raw_call_t &call) -> void;
auto visit(const koopa_raw_func_arg_ref_t &func_arg_ref) -> void;
auto visit(const koopa_raw_global_alloc_t &global_alloc) -> void;
auto visit(const koopa_raw_get_elem_ptr_t &get_elem_ptr) -> void;
auto visit(const koopa_raw_get_ptr_t &get_ptr) -> void;
/** @} */
};
} // namespace backend
82 changes: 73 additions & 9 deletions project/include/ir/ast.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export module ir.ast;

import symbol_table;
import ir_builder;
import ir.type;

/**
* @brief Namespace containing all AST related classes and functions.
Expand Down Expand Up @@ -59,6 +60,7 @@ public:

class LValAST;
class BlockAST;
class InitValStmtAST;

//* enum class
// clang-format off
Expand Down Expand Up @@ -98,23 +100,32 @@ public:
std::string btype;
std::string ident;
bool is_const;
bool is_ptr;
std::vector<std::unique_ptr<ExprAST>> indices;
/**
* @brief Constructs a function parameter.
* @param _btype The type of the parameter (e.g., "int").
* @param _ident The name of the parameter.
* @param _is_const Whether the parameter is constant.
*/
FuncParamAST(std::string _btype, std::string _ident, bool _is_const)
: btype(std::move(_btype)), ident(std::move(_ident)),
is_const(_is_const) {}
FuncParamAST(std::string _btype, std::string _ident, bool _is_const,
bool _is_ptr, std::vector<std::unique_ptr<ExprAST>> _indices)
: btype(std::move(_btype)), ident(std::move(_ident)), is_const(_is_const),
is_ptr(_is_ptr), indices(std::move(_indices)) {}
auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
auto toKoopa(ir::KoopaBuilder &builder) const -> std::string;
};

/**
* @brief Base class for definition AST nodes (variables, functions, arrays).
*/
class DefAST : public BaseAST {};

/**
* @brief AST node for function definitions.
*/
class FuncDefAST : public BaseAST {
class FuncDefAST : public DefAST {
public:
~FuncDefAST() override;
std::string btype;
Expand All @@ -135,10 +146,29 @@ public:
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
};

/**
* @brief AST node for array definitions.
*
* Handles both constant and non-constant array definitions, including their sizes and initializers.
*/
class ArrayDefAST : public DefAST {
public:
~ArrayDefAST() override;
bool is_const;
std::string ident;
std::vector<std::unique_ptr<ExprAST>> array_suffix;
std::unique_ptr<InitValStmtAST> init_val;
ArrayDefAST(bool _is_const, std::string _ident,
std::vector<std::unique_ptr<ExprAST>> _array_suffix,
InitValStmtAST *_init_val);
auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
};

/**
* @brief AST node for a single variable definition.
*/
class DefAST : public BaseAST {
class ScalarDefAST : public DefAST {
public:
bool is_const;
std::string ident;
Expand All @@ -149,7 +179,7 @@ public:
* @param _ident The name of the variable.
* @param _initVal The initial value expression (optional).
*/
DefAST(bool _is_const, std::string _ident, BaseAST *_initVal)
ScalarDefAST(bool _is_const, std::string _ident, BaseAST *_initVal)
: is_const(_is_const), ident(std::move(_ident)) {
if (_initVal) {
initVal.reset(static_cast<ExprAST *>(_initVal));
Expand Down Expand Up @@ -206,6 +236,38 @@ public:
auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
};

/**
* @brief Represents an initialization value statement in the abstract syntax
* tree.
*
* This class is used to model initialization values, which can be either a
* single expression or a list of nested initializers (e.g., for arrays or
* aggregate types).
*/
class InitValStmtAST : public StmtAST {
public:
std::unique_ptr<ExprAST> expr;
std::vector<std::unique_ptr<InitValStmtAST>> initialize_list;
/**
* @brief Constructs an InitValStmtAST object.
*
* @param _expr Pointer to a BaseAST that will be statically cast to ExprAST.
* It represents the primary initialization expression.
* @param _initialize_list Vector of unique pointers to InitValStmtAST for
* nested initialization. This list is moved into the member to avoid copying.
*/
InitValStmtAST(BaseAST *_expr,
std::vector<std::unique_ptr<InitValStmtAST>> _initialize_list)
: initialize_list(std::move(_initialize_list)) {
expr.reset(static_cast<ExprAST *>(_expr));
}

auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
auto flatten(std::shared_ptr<type::Type>, ir::KoopaBuilder &) const
-> std::vector<std::string>;
};
/** @} */

/** @name Data Action
Expand Down Expand Up @@ -242,9 +304,9 @@ public:
* @param _btype The type of the variables.
* @param _defs The list of variable definitions.
*/
DeclAST(bool _isConst, std::string _btype,
DeclAST(bool _is_const, std::string _btype,
std::vector<std::unique_ptr<DefAST>> _defs)
: is_const(_isConst), btype(std::move(_btype)), defs(std::move(_defs)) {}
: is_const(_is_const), btype(std::move(_btype)), defs(std::move(_defs)) {}
auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
};
Expand Down Expand Up @@ -345,11 +407,13 @@ public:
class LValAST : public ExprAST {
public:
std::string ident;
std::vector<std::unique_ptr<ExprAST>> indices;
/**
* @brief Constructs an LVal node.
* @param _ident The variable name.
*/
LValAST(std::string _ident) : ident(std::move(_ident)) {};
LValAST(std::string _ident, std::vector<std::unique_ptr<ExprAST>> _indices)
: ident(std::move(_ident)), indices(std::move(_indices)) {};
auto dump(int depth) const -> void override;
auto codeGen(ir::KoopaBuilder &builder) const -> std::string override;
auto CalcValue(ir::KoopaBuilder &builder) const -> int override;
Expand Down
2 changes: 0 additions & 2 deletions project/include/ir/ir_builder.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ public:
*/
auto resetCount() -> void {
count_reg = 0;
count_name = 0;
count_label = 0;
_is_block_closed = false;
}

Expand Down
8 changes: 4 additions & 4 deletions project/include/ir/symbol_table.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct Symbol {
std::string irName; ///< IR-level name (e.g., "@x_1")
std::shared_ptr<type::Type> type; ///< Data type of the symbol
SymbolKind kind; ///< Variable or Function
bool is_const; ///< True if it's a compile-time constant
bool is_const; ///< True if it's a compile-time constant
int constValue; ///< The value of the constant, if applicable
};

Expand Down Expand Up @@ -94,8 +94,8 @@ public:
* @param val Initial value if constant.
*/
auto define(const std::string &name, const std::string &irName,
std::shared_ptr<type::Type> type, SymbolKind kind,
bool is_const, int val = 0) -> void {
std::shared_ptr<type::Type> type, SymbolKind kind, bool is_const,
int val = 0) -> void {

if (scopes.back().contains(name)) {
Log::panic("Semantic Error: Redefinition of " + name);
Expand Down Expand Up @@ -127,7 +127,7 @@ public:
* @return Symbol* Pointer to the symbol if found, else nullptr.
*/
auto lookup(const std::string &name) -> Symbol * {
for (auto &scope : std::views::reverse(scopes)) {
for (auto &scope : scopes | std::views::reverse) {
auto it = scope.find(name);
if (it != scope.end()) {
return &(it->second);
Expand Down
Loading
Loading