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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: CI

on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
branches:
- '**'

jobs:
build-and-test:
Expand All @@ -19,7 +19,7 @@ jobs:
- name: fmt check
run: cargo fmt -- --check
- name: lint
run: cargo clippy -- -D warnings
run: cargo clippy
- name: build
run: cargo build --verbose
- name: run tests
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
**/*.rs.bk
.idea/
.idea/
.DS_Store
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "rustc-tape4"
name = "rustc_tape4"
version = "0.1.0"
edition = "2024"

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A learning‐by‐doing project
- **Basic types**
- `int` (32‑bit signed)
- `char` (8‑bit signed)
- `void`

- **Derived types**
- Single‑level pointers (`int*`, `char*`)
Expand All @@ -29,7 +30,7 @@ A learning‐by‐doing project
- Arithmetic: `+`, `-`, `*`, `/`, `%`
- Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`
- Logical: `!`, `&&`, `||`
- Bitwise: `&`, `|`
- Bitwise: `&`, `|`, `^`
- Compound assignment: `+=`, `-=`
- Increment / decrement: `++`, `--`
- Assignment: `=`
Expand Down
79 changes: 79 additions & 0 deletions grammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Grammar

```bnf
program ::= function*

function ::= function_declaration
| function_definition

function_declaration ::= type_specifier identifier "(" ( "void" | parameter_list )? ")" ";"
function_definition ::= type_specifier identifier "(" ( "void" | parameter_list )? ")" block

parameter_list ::= parameter ( "," parameter )*
parameter ::= type_specifier identifier ( "[" int_literal? "]" )?

type_specifier ::= ( "int" | "char" | "void" ) "*"*

block ::= "{" statement* "}"

statement ::= block
| if_statement
| while_statement
| for_statement
| return_statement
| break_statement
| continue_statement
| declaration_statement
| expression_statement

declaration_statement ::= type_specifier init_declarator_list ";"
init_declarator_list ::= init_declarator ( "," init_declarator )*
init_declarator ::= declarator ( "=" initializer )?
declarator ::= identifier ( "[" int_literal "]" )?

initializer ::= expression
| "{" initializer_list? "}"
initializer_list ::= initializer ( "," initializer )* ","?

expression_statement ::= expression? ";"

if_statement ::= "if" "(" expression ")" statement ( "else" statement )?
while_statement ::= "while" "(" expression ")" statement
for_statement ::= "for" "(" expression? ";" expression? ";" expression? ")" statement
return_statement ::= "return" expression? ";"
break_statement ::= "break" ";"
continue_statement ::= "continue" ";"

expression ::= assignment
assignment ::= logical_or ( ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" ) assignment )?

logical_or ::= logical_and ( "||" logical_and )*
logical_and ::= bitwise_or ( "&&" bitwise_or )*
bitwise_or ::= bitwise_xor ( "|" bitwise_xor )*
bitwise_xor ::= bitwise_and ( "^" bitwise_and )*
bitwise_and ::= equality ( "&" equality )*

equality ::= relational ( ( "==" | "!=" ) relational )*
relational ::= additive ( ( "<" | "<=" | ">" | ">=" ) additive )*
additive ::= multiplicative ( ( "+" | "-" ) multiplicative )*
multiplicative ::= unary ( ( "*" | "/" | "%" ) unary )*

unary ::= ( "!" | "-" | "&" | "*" | "++" | "--" ) unary
| postfix
postfix ::= primary postfix_op*
postfix_op ::= "(" argument_list? ")"
| "[" expression "]"
| "++"
| "--"

primary ::= identifier
| int_literal
| char_literal
| "(" expression ")"
| "{" initializer_list? "}"

argument_list ::= expression ( "," expression )*

identifier ::= /* Ident(String) */
int_literal ::= /* IntLiteral(i64) */
char_literal ::= /* CharLiteral(char) */
86 changes: 86 additions & 0 deletions src/ast/expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Ident(String), // variable or function name
IntLiteral(i64),
CharLiteral(char),

// 단항연산자
UnaryPrefixOp {
op: PrefixOp,
rhs: Box<Expr>,
},
UnaryPostfixOp {
lhs: Box<Expr>,
op: PostfixOp,
},

BinaryOp {
lhs: Box<Expr>,
op: BinaryOp,
rhs: Box<Expr>,
}, // 이항연산자
Call {
func: Box<Expr>,
args: Vec<Expr>,
}, // 함수 호출
ArrayIndex {
array: Box<Expr>,
index: Box<Expr>,
}, // 인덱싱
InitializerList(Vec<Expr>), // 배열 초기화 ex) {1, 2, 3}

Assignment {
left: Box<Expr>,
op: AssignOp,
right: Box<Expr>,
}, // 할당 x = y, x += 1.
}

#[derive(Debug, Clone, PartialEq)]
pub enum PrefixOp {
Address, // &
Deref, // *
Neg, // -
Not, // !
PreInc, // ++x
PreDec, // --x
}

#[derive(Debug, Clone, PartialEq)]
pub enum PostfixOp {
PostInc, // x++
PostDec, // x--
}

#[derive(Debug, Clone, PartialEq)]
pub enum BinaryOp {
Add, // +
Sub, // -
Mul, // *
Div, // /
Rem, // %
Eq, // ==
Ne, // !=
Lt, // <
Le, // <=
Gt, // >
Ge, // >=
And, // &&
Or, // ||
BitAnd, // &
BitOr, // |
BitXor, // ^
}

#[derive(Clone, Debug, PartialEq)]
pub enum AssignOp {
Assign, // =
PlusAssign, // +=
MinusAssign, // -=
MulAssign, // *=
DivAssign, // /=
RemAssign, // %=
BitAndAssign, // &=
BitOrAssign, // |=
BitXorAssign, // ^=
}
24 changes: 24 additions & 0 deletions src/ast/functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::ast::stmt::Block;
use crate::ast::ty::TypeSpecifier;

#[derive(Debug, Clone)]
pub struct Parameter {
pub name: String,
pub ty: TypeSpecifier,
}

#[derive(Debug, Clone)]
pub struct Function {
pub name: String,
pub return_ty: TypeSpecifier,
pub params: Vec<Parameter>,
pub body: Block,
}

// 함수 정의: 반환 타입, 함수 이름, 매개변수 목록, 함수 본문
// function_definition ::= type_specifier identifier "(" parameter_list? ")" block

// 매개변수 목록: 첫 매개변수 + 쉼표로 구분된 추가 매개변수 0개 이상
// parameter_list ::= parameter ( "," parameter )*
// 단일 매개변수: 타입 + 이름
// parameter ::= type_specifier identifier
11 changes: 11 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pub mod expr;
pub mod functions;
pub mod program;
pub mod stmt;
pub mod ty;

pub use expr::Expr;
pub use functions::Function;
pub use program::Program;
pub use stmt::Stmt;
pub use ty::TypeSpecifier;
9 changes: 9 additions & 0 deletions src/ast/program.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::ast::Function;

#[derive(Debug, Clone)]
pub struct Program {
pub functions: Vec<Function>,
}

// 프로그램 전체: 0개 이상의 함수 정의
// program ::= function_definition*
53 changes: 53 additions & 0 deletions src/ast/stmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::ast::TypeSpecifier;
use crate::ast::expr::Expr;

#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub statements: Vec<Stmt>,
}

#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
Block(Block),
If {
cond: Expr,
then_branch: Box<Stmt>,
else_branch: Option<Box<Stmt>>,
},
While {
cond: Expr,
body: Box<Stmt>,
},
For {
init: Option<Box<Stmt>>,
cond: Option<Expr>,
step: Option<Expr>,
body: Box<Stmt>,
},
Return(Option<Expr>),
Break,
Continue,
Declaration {
ty: TypeSpecifier,
declarators: Vec<Declarator>,
},
ExprStmt(Option<Expr>),
}

#[derive(Debug, Clone, PartialEq)]
pub struct Declarator {
pub name: String,
pub array_size: Option<i64>,
pub init: Option<Expr>,
}

// 문장: 구문들
// statement ::= block
// | if_statement
// | while_statement
// | for_statement
// | return_statement
// | break_statement
// | continue_statement
// | declaration_statement
// | expression_statement
10 changes: 10 additions & 0 deletions src/ast/ty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[derive(Debug, Clone, PartialEq)]
pub enum TypeSpecifier {
Int,
Char,
Void,
Pointer(Box<TypeSpecifier>),
}

// 타입 지정자: 기본 타입(int|char|void) + 0개 이상 포인터
// type_specifier ::= ( "int" | "char" | "void" ) "*"*
Loading
Loading