Skip to content

ikura-hamu/ooo

Repository files navigation

ooo

Toy Go Compiler

ooo (pronounced /oːo/, in Japanese 「おおお」,) is a toy Go compiler. It reads (subsets of) Go programs and generates x86_64 assembly code.

How to do self hosting

rm -f *.s
# Build 1st generation ooo
go build -o ooo1 .
# Generate 2nd generation assembly code
./ooo1 < go_files.txt > ooo2.s
# Build 2nd generation ooo
cc -Wa,--noexecstack -fPIE -g -o ooo2 ooo2.s asm/syscall.s asm/print.s asm/readAll.s asm/mem.s asm/files.s
# Generate 3rd generation assembly code
./ooo2 < go_files.txt > ooo3.s
# Check if ooo2 and ooo3 are identical
diff ooo2.s ooo3.s

Supported Syntax

program    = packageClause ";" ( (funcDecl | varDecl | typeDecl | constDecl) ";" )*
packageClause = "package" ident
funcDecl   = "func" ident parameters result? compStmt?
parameters = "(" (parameterDecl, ("," parameterDecl)* ","? )? ")"
parameterDecl = ident type
type       = ident | "*" type | arrayType | sliceType | structType
arrayType  = "[" num "]" type
sliceType  = "[" "]" type
structType = "struct" "{" ( fieldDecl ";" )* "}"
fieldDecl  = ident type
selector   = "." ident
result     = type
stmt       = "return" expr?
            | "continue"
            | "break"
            | ifStmt
            | forStmt
            | varDecl
            | constDecl
            | typeDecl
            | gotoStmt
            | labeledStmt
            | assign
            | emptyStmt
forStmt    = "for" (stmt? ";" expr? ";" stmt?)? compStmt
compStmt   = "{" (stmt ";" )* "}"
ifStmt     = "if" expr compStmt ( "else" (compStmt | ifStmt) )?
gotoStmt   = "goto" ident
labeledStmt = ident ":" stmt
emptyStmt  = ""
varDecl    = "var" ident type
constDecl  = "const" ident type "=" expr
typeDecl   = "type" ident type
assign     = expr ( "=" expr)?
expr       = or
or         = and ( "||" and )*
and        = equality ( "&&" equality )*
equality   = relational ("==" relational | "!=" relational)*
relational = add ("<" add | "<=" add | ">" add | ">=" add)*
add        = mul ("+" mul | "-" mul)*
mul        = unary ("*" unary | "/" unary)*
unary      = ("+" | "-")? primary | "*" unary | "&" unary | "!" unary
index      = "[" expr "]"
slice      = "[" expr ":" expr "]"
compLit    = litType litValue
litType    = arrayType | sliceType | structType | ident
litValue   = "{" ( elemList (",")?  )?  "}"
elemList   = keyedElem ( "," keyedElem )*
keyedElemKey = expr | ident
keyedElem  = keyedElemKey ":" expr | expr
primary    = num
            | str
            | "(" expr ")"
            | ident ( "(" ( expr | type ("," expr)* ","? )? ")" )?
            | compLit
            | primary index
            | primary slice
            | primary selector
str     = `"` { any char except `"` } `"`

About

Toy Go Compiler

Topics

Resources

Stars

Watchers

Forks

Contributors