├── .gitmodules ├── .travis.yml ├── README.md ├── _resources_ ├── Assignment 1: Lexical Analysis.html ├── Assignment 1: Lexical Analysis_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── Assignment 2: Syntactic Analysis.html ├── Assignment 2: Syntactic Analysis_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── Assignment 3: Semantic Analysis.html ├── Assignment 3: Semantic Analysis_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── Assignment 4: Intermediate Code.html ├── Assignment 4: Intermediate Code_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── Assignment 5: MIPS Assembly Code.html ├── Assignment 5: MIPS Assembly Code_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── Intermediate code.html ├── Introduction, Lexical analysis.html ├── MIPS and code generation.html ├── Parsers, syntax trees.html ├── Semantic analysis.html ├── Semantic analysis_files │ ├── In%2520the%2520body%2520of%2520a%2520function%2520the%2520fo.htm │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm ├── The uC language.html ├── The uC language_files │ ├── my-slides.htm │ ├── opera.htm │ ├── outline.htm │ ├── print.htm │ └── slides.htm └── ucc-smlnj-student-2012-01-13 │ ├── Makefile │ ├── absyn │ ├── absyn-check.sml │ ├── absyn-print.sml │ ├── absyn.sig │ └── absyn.sml │ ├── codegen │ ├── assem-print.sig │ ├── assem.sig │ ├── codegen.sig │ └── insns.sig │ ├── lexer │ ├── lexarg.sig │ ├── lexarg.sml │ └── uc.lex │ ├── main │ ├── link.sml │ ├── main.sml │ ├── make.sml │ └── start.sml │ ├── mips │ ├── mips-assem-print.sml │ ├── mips-codegen.sml │ ├── mips.sig │ └── mips.sml │ ├── parser │ ├── fake-parse.sml │ ├── parse.sig │ ├── parse.sml │ └── uc.grm │ ├── rtl │ ├── absyn-to-rtl.sml │ ├── rtl-print.sml │ ├── rtl.sig │ └── rtl.sml │ ├── sources.cm │ ├── ucc.sh │ └── util │ ├── aa-dict-fn.sml │ ├── ord-dict-sig.sml │ ├── source.sig │ └── source.sml ├── ast ├── ast.go ├── astutil │ ├── astutil.go │ └── walk.go ├── astx │ ├── astx.go │ └── type.go └── types.go ├── cmd ├── 3rdpartycompile │ └── 3rdpartycompile.go ├── internal │ └── debug │ │ └── debug.go ├── uclang │ └── uclang.go ├── ulex │ └── ulex.go ├── uparse │ └── uparse.go └── usem │ └── usem.go ├── compile.sh ├── go.mod ├── go.sum ├── gocc ├── Makefile ├── errors │ └── errors.go ├── lexer │ ├── acttab.go │ ├── lexer.go │ ├── lexer_test.go │ └── transitiontable.go ├── parser │ ├── action.go │ ├── actiontable.go │ ├── error.go │ ├── gototable.go │ ├── parser.go │ ├── parser_test.go │ └── productionstable.go ├── scanner │ ├── scanner.go │ └── scanner_test.go ├── token │ └── token.go ├── uc.bnf └── util │ ├── litconv.go │ └── rune.go ├── hand ├── lexer │ ├── example_test.go │ ├── keywords.go │ ├── lexer.go │ ├── lexer_test.go │ └── state.go └── scanner │ └── scanner.go ├── irgen ├── emit.go ├── irgen.go ├── irgen_test.go ├── lower.go └── util.go ├── noisy.sh ├── presentation ├── 01_lex │ └── notes.md ├── 02_parse │ └── notes.md ├── 03_sem │ └── notes.md ├── 04_05_irgen │ └── notes.md └── testcases.patch ├── report ├── .gitignore ├── 1_intro.tex ├── 2_lex.tex ├── 3_parse.tex ├── 4_sem.tex ├── 5_ir.tex ├── 6_ir_gen.tex ├── 7_con.tex ├── Makefile ├── app.tex ├── inc │ ├── Makefile │ ├── sections │ │ ├── 2_lexical_analysis │ │ │ └── uc.bnf │ │ ├── 3_syntactic_analysis │ │ │ ├── ast_doc.pdf │ │ │ └── uc.bnf │ │ ├── 4_semantic_analysis │ │ │ └── types_doc.pdf │ │ └── 6_ir_generation │ │ │ ├── r06.c │ │ │ └── r06.ll │ ├── ulex │ │ └── Makefile │ ├── uparse │ │ └── Makefile │ └── usem │ │ └── Makefile ├── preamble.sty ├── references.bib ├── sections │ ├── 1_introduction.tex │ ├── 1_introduction │ │ ├── 1_project_aim_and_objectives.tex │ │ └── 2_deliverables.tex │ ├── 2_lexical_analysis.tex │ ├── 2_lexical_analysis │ │ ├── 1_design_decisions.tex │ │ ├── 2_implementation.tex │ │ └── 3_validation.tex │ ├── 3_syntactic_analysis.tex │ ├── 3_syntactic_analysis │ │ ├── 1_design_decisions.tex │ │ ├── 2_implementation.tex │ │ └── 3_validation.tex │ ├── 4_semantic_analysis.tex │ ├── 4_semantic_analysis │ │ ├── 1_design_decisions.tex │ │ ├── 2_implementation.tex │ │ └── 3_validation.tex │ ├── 5_intermediate_representation.tex │ ├── 5_intermediate_representation │ │ ├── 1_design_decisions.tex │ │ ├── 2_implementation.tex │ │ └── 3_validation.tex │ ├── 6_ir_generation.tex │ ├── 6_ir_generation │ │ ├── 1_installation_and_usage.tex │ │ ├── 2_design_decisions.tex │ │ ├── 3_implementation.tex │ │ └── 4_validation.tex │ ├── 7_conclusion.tex │ ├── 7_conclusion │ │ ├── 1_project_summary.tex │ │ ├── 2_future_work.tex │ │ └── 3_final_thoughts.tex │ ├── appendices.tex │ └── appendices │ │ ├── 2_lexical_analysis.tex │ │ ├── 3_syntactic_analysis.tex │ │ ├── 4_semantic_analysis.tex │ │ ├── 5_intermediate_representation.tex │ │ └── informal_grammar_for_uc.tex └── uc.tex ├── sem ├── errors │ └── errors.go ├── resolve.go ├── scope.go ├── sem.go ├── sem_test.go ├── semcheck │ └── semcheck.go └── typecheck │ ├── deduce.go │ └── typecheck.go ├── testdata ├── Makefile ├── encoding │ └── lexer │ │ ├── big5.c │ │ ├── iso-8859-1.c │ │ ├── utf-16be_bom.c │ │ ├── utf-16le_bom.c │ │ ├── utf-8.c │ │ └── utf-8_bom.c ├── extra │ ├── irgen │ │ ├── Makefile │ │ ├── array_arg.c │ │ ├── array_arg.ll │ │ ├── array_ident_def.c │ │ ├── array_ident_def.ll │ │ ├── array_ident_use.c │ │ ├── array_ident_use.ll │ │ ├── array_param.c │ │ ├── array_param.ll │ │ ├── binary_expr_add.c │ │ ├── binary_expr_add.ll │ │ ├── binary_expr_assign.c │ │ ├── binary_expr_assign.ll │ │ ├── binary_expr_div.c │ │ ├── binary_expr_div.ll │ │ ├── binary_expr_eq.c │ │ ├── binary_expr_eq.ll │ │ ├── binary_expr_ge.c │ │ ├── binary_expr_ge.ll │ │ ├── binary_expr_gt.c │ │ ├── binary_expr_gt.ll │ │ ├── binary_expr_land.c │ │ ├── binary_expr_land.ll │ │ ├── binary_expr_le.c │ │ ├── binary_expr_le.ll │ │ ├── binary_expr_lt.c │ │ ├── binary_expr_lt.ll │ │ ├── binary_expr_mul.c │ │ ├── binary_expr_mul.ll │ │ ├── binary_expr_ne.c │ │ ├── binary_expr_ne.ll │ │ ├── binary_expr_sub.c │ │ ├── binary_expr_sub.ll │ │ ├── call_expr.c │ │ ├── call_expr.ll │ │ ├── call_expr_cast.c │ │ ├── call_expr_cast.ll │ │ ├── call_expr_multi_args.c │ │ ├── call_expr_multi_args.ll │ │ ├── call_expr_multi_args_cast.c │ │ ├── call_expr_multi_args_cast.ll │ │ ├── expr_ret.c │ │ ├── expr_ret.ll │ │ ├── expr_stmt.c │ │ ├── expr_stmt.ll │ │ ├── func_param.c │ │ ├── func_param.ll │ │ ├── global_array_arg.c │ │ ├── global_array_arg.ll │ │ ├── global_array_ident_def.c │ │ ├── global_array_ident_def.ll │ │ ├── global_array_ident_use.c │ │ ├── global_array_ident_use.ll │ │ ├── global_array_param.c │ │ ├── global_array_param.ll │ │ ├── global_def.c │ │ ├── global_def.ll │ │ ├── global_index_expr_def.c │ │ ├── global_index_expr_def.ll │ │ ├── global_index_expr_use.c │ │ ├── global_index_expr_use.ll │ │ ├── global_ret.c │ │ ├── global_ret.ll │ │ ├── if_else_stmt.c │ │ ├── if_else_stmt.ll │ │ ├── if_stmt.c │ │ ├── if_stmt.ll │ │ ├── implicit_void_ret.c │ │ ├── implicit_void_ret.ll │ │ ├── index_expr.c │ │ ├── index_expr.ll │ │ ├── index_expr_def.c │ │ ├── index_expr_def.ll │ │ ├── index_expr_use.c │ │ ├── index_expr_use.ll │ │ ├── int_ident_def.c │ │ ├── int_ident_def.ll │ │ ├── int_ident_use.c │ │ ├── int_ident_use.ll │ │ ├── int_ret.c │ │ ├── int_ret.ll │ │ ├── issue_68_if_land.c │ │ ├── issue_68_if_land.ll │ │ ├── issue_68_nested_if.c │ │ ├── issue_68_nested_if.ll │ │ ├── issue_68_nested_if_while.c │ │ ├── issue_68_nested_if_while.ll │ │ ├── issue_68_while_land.c │ │ ├── issue_68_while_land.ll │ │ ├── issue_69_trunc_arg.c │ │ ├── issue_69_trunc_arg.ll │ │ ├── issue_70_if_ret.c │ │ ├── issue_70_if_ret.ll │ │ ├── issue_70_while_ret.c │ │ ├── issue_70_while_ret.ll │ │ ├── issue_73_pointer_pointer_ref.c │ │ ├── issue_73_pointer_pointer_ref.ll │ │ ├── issue_73_pointer_pointer_use.c │ │ ├── issue_73_pointer_pointer_use.ll │ │ ├── local_def.c │ │ ├── local_def.ll │ │ ├── nested_var_decl.c │ │ ├── nested_var_decl.ll │ │ ├── paren_expr.c │ │ ├── paren_expr.ll │ │ ├── post_strip.sh │ │ ├── strip.sh │ │ ├── tentative_def.c │ │ ├── tentative_def.ll │ │ ├── unary_expr_not.c │ │ ├── unary_expr_not.ll │ │ ├── unary_expr_sub.c │ │ ├── unary_expr_sub.ll │ │ ├── void_ret.c │ │ ├── void_ret.ll │ │ ├── while_stmt.c │ │ └── while_stmt.ll │ ├── lexer │ │ ├── illegal-utf8-char-lit.c │ │ ├── invalid-esc.c │ │ └── multibyte-char-lit.c │ └── semantic │ │ ├── extra-void-arg.c │ │ ├── incompatible-arg-type.c │ │ ├── index-array.c │ │ ├── int-redef.c │ │ ├── local-var-redef.c │ │ ├── missing-return-main.c │ │ ├── missing-return.c │ │ ├── nested-function-def.c │ │ ├── param-redef.c │ │ ├── tentative-var-def.c │ │ ├── unnamed-arg.c │ │ ├── variable-sized-array-arg.c │ │ ├── variable-sized-array.c │ │ ├── void-array-arg.c │ │ ├── void-array.c │ │ ├── void-param.c │ │ ├── void-params.c │ │ └── void-var.c ├── incorrect │ ├── lexer │ │ ├── bad.c │ │ ├── good.c │ │ ├── long-char.c │ │ └── ugly.c │ ├── parser │ │ ├── pe01.c │ │ ├── pe02.c │ │ ├── pe03.c │ │ ├── pe04.c │ │ ├── pe05.c │ │ ├── pe06.c │ │ ├── pe07.c │ │ ├── pe08.c │ │ ├── pe09.c │ │ ├── pe10.c │ │ ├── pe11.c │ │ ├── pe12.c │ │ ├── pe13.c │ │ └── pe14.c │ └── semantic │ │ ├── se01.c │ │ ├── se02.c │ │ ├── se03.c │ │ ├── se04.c │ │ ├── se05.c │ │ ├── se06.c │ │ ├── se07.c │ │ ├── se08.c │ │ ├── se09.c │ │ ├── se10.c │ │ ├── se11.c │ │ ├── se12.c │ │ ├── se13.c │ │ ├── se14.c │ │ ├── se15.c │ │ ├── se16.c │ │ ├── se17.c │ │ ├── se18.c │ │ ├── se19.c │ │ ├── se20.c │ │ ├── se21.c │ │ ├── se22.c │ │ ├── se23.c │ │ ├── se24.c │ │ ├── se25.c │ │ ├── se26.c │ │ ├── se27.c │ │ ├── se28.c │ │ ├── se29.c │ │ ├── se30.c │ │ ├── se31.c │ │ ├── se32.c │ │ ├── se33.c │ │ └── se34.c ├── noisy │ ├── advanced │ │ ├── 8queens.c │ │ ├── bubble.c │ │ ├── eval.c │ │ ├── primes.c │ │ └── quick.c │ ├── medium │ │ ├── circle.c │ │ ├── fac-b.c │ │ ├── fac.c │ │ └── fib.c │ └── simple │ │ ├── sim01.c │ │ ├── sim02.c │ │ ├── sim03.c │ │ ├── sim04.c │ │ ├── sim05.c │ │ ├── sim06.c │ │ ├── sim07.c │ │ ├── sim08.c │ │ ├── sim09.c │ │ ├── sim10.c │ │ └── sim11.c ├── quiet │ ├── lexer │ │ ├── 00README.txt │ │ ├── l01.c │ │ ├── l02.c │ │ ├── l03.c │ │ ├── l04.c │ │ ├── l05.c │ │ └── l06.c │ ├── mips │ │ ├── m01.c │ │ ├── m02.c │ │ └── m03.c │ ├── parser │ │ ├── 00README.txt │ │ ├── p01.c │ │ ├── p02.c │ │ ├── p03.c │ │ ├── p04.c │ │ ├── p05.c │ │ ├── p06.c │ │ ├── p07.c │ │ └── p08.c │ ├── rtl │ │ ├── r01.c │ │ ├── r02.c │ │ ├── r03.c │ │ ├── r04.c │ │ ├── r05.c │ │ └── r06.c │ └── semantic │ │ ├── 00README.txt │ │ ├── s01.c │ │ ├── s02.c │ │ ├── s03.c │ │ ├── s04.c │ │ ├── s05.c │ │ └── s06.c └── uc.c ├── token ├── kind_string.go ├── token.go └── token_test.go └── types ├── basickind_string.go └── types.go /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "report/latex"] 2 | path = report/latex 3 | url = https://github.com/mewpaper/latex.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.6 4 | 5 | notifications: 6 | email: false 7 | 8 | env: 9 | global: 10 | - secure: "GHO7qIUJdfxLVEANbBvUwvyqmOSjOcChXK/99l4Dxo9ayrVaOPxe5YEYPtfWDdaGtLwdaQ/vIi5keUjvMDtmjiqvsxYyRR43oFQTJCIcRdCUEtKSg352LnCvyO+bZyaZr+6b+Pnz8sikk80Z273QHSlzLq5Cw9wYbeVnVXjMFAqjejWPe0Gj09ff4J9/p+FSxm93f11r8iExC7b7ybuk7odCt09dN6k4bz6Lat7AgamSAY28BGuecaHYlHVhK6G9x6CgEeheExfXwW+TlQtXuTYhpb2kULSiXrFBNbkjzsCc6vfmpmCi2gqbpmsOKiaXA2P05dzBv5AyXWhXbexFREJ1gfHwmpgfJBkTwsqfRXi46sQX+nRuMMUDY9CSqTFHFvNYjRRa87drfqRyWLr0atpg+GH7IN7xNw6nimvvlNQ72ZnQKAPXiDRtw49WlKjDmmx2BwdygIQq5kdg0cvHcDjeOCYUXtjw47aM60/ar+oG5Za1JWb7ugUBrlaHMRFB4Bv4VXrZsi0H4pQl11arqzxu5Vei4nxVXCowQWWhXYcOFAtwy10vzhGqSy/1urZLhiLrXZvahLOsnZczvhn9Srizl7pvKouS9Iya+3EBZ20QGvsUidiYe1rdJ1qQ6QIa2zYWoV9eNO5MriR6FxcBa+s37TdWxHbfE9LiDKMw67Y=" 11 | - PATH=$HOME/gopath/bin:$PATH 12 | 13 | before_install: 14 | - go get golang.org/x/tools/cmd/cover 15 | - go get golang.org/x/tools/cmd/goimports 16 | - go get github.com/golang/lint/golint 17 | - go get github.com/mattn/goveralls 18 | - go get github.com/goccmack/gocc 19 | - make -C $HOME/gopath/src/github.com/mewmew/uc/gocc gen 20 | 21 | install: 22 | - go get ./... 23 | 24 | before_script: 25 | - export GOLINT_IGNORE="-not -wholename '*/gocc/*' -not -name '*_string.go'" 26 | - wget https://gist.github.com/mewmew/379014c9a2e6885e238d/raw/goclean.sh 27 | - chmod +x goclean.sh 28 | 29 | script: 30 | - ./goclean.sh 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # µC Compiler 2 | 3 | [![Build Status](https://travis-ci.org/mewmew/uc.svg?branch=dev)](https://travis-ci.org/mewmew/uc) 4 | [![Coverage Status](https://coveralls.io/repos/github/mewmew/uc/badge.svg?branch=dev)](https://coveralls.io/github/mewmew/uc?branch=dev) 5 | [![GoDoc](https://godoc.org/github.com/mewmew/uc?status.svg)](https://godoc.org/github.com/mewmew/uc) 6 | 7 | A compiler for the [µC programming language](https://www.it.uu.se/katalog/aleji304/CompilersProject/uc.html). 8 | 9 | ## Installation 10 | 11 | 1. [Install Go](https://golang.org/doc/install). 12 | 2. Install Gocc `go get github.com/goccmack/gocc`. 13 | 14 | ``` 15 | $ go get -u github.com/mewmew/uc 16 | $ cd ${GOPATH}/src/github.com/mewmew/uc/gocc 17 | $ make gen 18 | $ go get github.com/mewmew/uc/... 19 | $ go install github.com/mewmew/uc/cmd/ulex 20 | $ go install github.com/mewmew/uc/cmd/uparse 21 | $ go install github.com/mewmew/uc/cmd/uclang 22 | $ go install github.com/mewmew/uc/cmd/3rdpartycompile 23 | ``` 24 | 25 | ## Usage 26 | 27 | * [ulex](https://godoc.org/github.com/mewmew/uc/cmd/ulex): a lexer for the µC language which pretty-prints tokens to standard output. 28 | * [uparse](https://godoc.org/github.com/mewmew/uc/cmd/uparse): a parser for the µC language which pretty-prints abstract syntax trees to standard output. 29 | * [usem](https://godoc.org/github.com/mewmew/uc/cmd/usem): a static semantic checker for the µC language which validates the input and reports errors to standard error. 30 | * [uclang](https://godoc.org/github.com/mewmew/uc/cmd/uclang): a compiler for the µC language which validates the input, and prints corresponding LLVM IR assembly to standard output. 31 | * [3rdpartycompile](https://godoc.org/github.com/mewmew/uc/cmd/3rdpartycompile): a compiler for the µC language which through the uclang tool chain validates the input, compiles to LLVM and through the third party compiler clang links with the supplied lib uc.c and outputs the corresponding binary. 32 | 33 | ## Public domain 34 | 35 | The source code and any original content of this repository is hereby released into the [public domain]. 36 | 37 | [public domain]: https://creativecommons.org/publicdomain/zero/1.0/ 38 | -------------------------------------------------------------------------------- /_resources_/Assignment 1: Lexical Analysis_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 1: Lexical Analysis_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 1: Lexical Analysis_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 1: Lexical Analysis_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Assignment 1: Lexical Analysis_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 1: Lexical Analysis_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Assignment 1: Lexical Analysis_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 1: Lexical Analysis_files/print.htm -------------------------------------------------------------------------------- /_resources_/Assignment 1: Lexical Analysis_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 1: Lexical Analysis_files/slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 2: Syntactic Analysis_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 2: Syntactic Analysis_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 2: Syntactic Analysis_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 2: Syntactic Analysis_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Assignment 2: Syntactic Analysis_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 2: Syntactic Analysis_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Assignment 2: Syntactic Analysis_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 2: Syntactic Analysis_files/print.htm -------------------------------------------------------------------------------- /_resources_/Assignment 2: Syntactic Analysis_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 2: Syntactic Analysis_files/slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 3: Semantic Analysis_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 3: Semantic Analysis_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 3: Semantic Analysis_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 3: Semantic Analysis_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Assignment 3: Semantic Analysis_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 3: Semantic Analysis_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Assignment 3: Semantic Analysis_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 3: Semantic Analysis_files/print.htm -------------------------------------------------------------------------------- /_resources_/Assignment 3: Semantic Analysis_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 3: Semantic Analysis_files/slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 4: Intermediate Code_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 4: Intermediate Code_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 4: Intermediate Code_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 4: Intermediate Code_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Assignment 4: Intermediate Code_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 4: Intermediate Code_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Assignment 4: Intermediate Code_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 4: Intermediate Code_files/print.htm -------------------------------------------------------------------------------- /_resources_/Assignment 4: Intermediate Code_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 4: Intermediate Code_files/slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 5: MIPS Assembly Code_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 5: MIPS Assembly Code_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Assignment 5: MIPS Assembly Code_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 5: MIPS Assembly Code_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Assignment 5: MIPS Assembly Code_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 5: MIPS Assembly Code_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Assignment 5: MIPS Assembly Code_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 5: MIPS Assembly Code_files/print.htm -------------------------------------------------------------------------------- /_resources_/Assignment 5: MIPS Assembly Code_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Assignment 5: MIPS Assembly Code_files/slides.htm -------------------------------------------------------------------------------- /_resources_/Intermediate code.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Intermediate code.html -------------------------------------------------------------------------------- /_resources_/Introduction, Lexical analysis.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Introduction, Lexical analysis.html -------------------------------------------------------------------------------- /_resources_/Semantic analysis.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis.html -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/In%2520the%2520body%2520of%2520a%2520function%2520the%2520fo.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/In%2520the%2520body%2520of%2520a%2520function%2520the%2520fo.htm -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/opera.htm -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/outline.htm -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/print.htm -------------------------------------------------------------------------------- /_resources_/Semantic analysis_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/Semantic analysis_files/slides.htm -------------------------------------------------------------------------------- /_resources_/The uC language_files/my-slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/The uC language_files/my-slides.htm -------------------------------------------------------------------------------- /_resources_/The uC language_files/opera.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/The uC language_files/opera.htm -------------------------------------------------------------------------------- /_resources_/The uC language_files/outline.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/The uC language_files/outline.htm -------------------------------------------------------------------------------- /_resources_/The uC language_files/print.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/The uC language_files/print.htm -------------------------------------------------------------------------------- /_resources_/The uC language_files/slides.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/_resources_/The uC language_files/slides.htm -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for the Micro-C compiler 2 | SHELL=/bin/sh 3 | 4 | GENERATED=lexer/uc.lex.sml parser/uc.grm.sml parser/uc.grm.sig parser/uc.grm.desc 5 | 6 | all: 7 | cat main/make.sml | sml 8 | 9 | distclean realclean: clean 10 | rm -rf */.cm 11 | rm -f $(GENERATED) 12 | 13 | clean: 14 | rm -f ucc.*-* 15 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/absyn/absyn-check.sml: -------------------------------------------------------------------------------- 1 | (* absyn/absyn-check.sml *) 2 | 3 | signature ABSYN_CHECK = 4 | sig 5 | structure Absyn: ABSYN 6 | val program: Absyn.program -> unit 7 | end (* signature ABSYN_CHECK *) 8 | 9 | functor AbsynCheckFn(Absyn : ABSYN) : ABSYN_CHECK = 10 | struct 11 | 12 | structure Absyn = Absyn 13 | 14 | (* 15 | * Reporting errors. 16 | * 17 | * Source file context is not easily available everywhere, so 18 | * a detected error is instead thrown as an exception. 19 | * At the top level where we do have the source file context, 20 | * we catch this exception and generate appropriate messages 21 | * before re-throwing the exception. 22 | * Limitation: We can't continue after an error. Big deal. 23 | *) 24 | 25 | type msg = string * int * int (* same as what Absyn.Source.sayMsg wants *) 26 | exception AbsynCheckError of msg list 27 | 28 | fun withSource(source, f) = 29 | f() 30 | handle (exn as AbsynCheckError(msgs)) => 31 | (List.app (Absyn.Source.sayMsg source) msgs; 32 | raise exn) 33 | 34 | fun error1 msg = raise AbsynCheckError[msg] 35 | 36 | fun error2(msg1, msg2) = raise AbsynCheckError[msg1, msg2] 37 | 38 | fun mkIdErrorMsg(msg, Absyn.IDENT(name, left, right)) = 39 | ("Error: "^msg^name, left, right) 40 | fun idError(msg, id) = error1(mkIdErrorMsg(msg, id)) 41 | 42 | fun doError(msg, left, right) = error1("Error: "^msg, left, right) 43 | fun expError(msg, Absyn.EXP(_,left,right)) = doError(msg, left, right) 44 | fun stmtError(msg, Absyn.STMT(_,left,right)) = doError(msg, left, right) 45 | 46 | (* 47 | * YOUR CODE HERE 48 | * 49 | * Hints: 50 | * - You need to represent uC types. 51 | * - You need an environment/symbol-table for identifiers. 52 | * - You need recursive functions over expressions and statements. 53 | * - You need to check type constraints at various places. 54 | * - Abstract syntax 'declarators' aren't types. You'll need 55 | * to translate them. 56 | * - You need to process top-level declarations. 57 | *) 58 | 59 | fun checkDeclarations _ = () (* XXX: REPLACE WITH YOUR CODE *) 60 | 61 | (* Programs *) 62 | 63 | fun program(Absyn.PROGRAM{decs,source}) = 64 | let fun check() = checkDeclarations decs 65 | in 66 | withSource(source, check) 67 | end 68 | 69 | end (* functor AbsynCheckFn *) 70 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/absyn/absyn.sig: -------------------------------------------------------------------------------- 1 | (* absyn/absyn.sig *) 2 | 3 | signature ABSYN = 4 | sig 5 | 6 | structure Source : SOURCE 7 | 8 | datatype ident 9 | = IDENT of string * int * int 10 | 11 | (* TYPES & DECLARATORS *) 12 | 13 | datatype baseTy 14 | = INTty 15 | | CHARty 16 | | VOIDty 17 | 18 | datatype declarator 19 | = VARdecl of ident 20 | | ARRdecl of ident * int option 21 | 22 | (* EXPRESSIONS *) 23 | 24 | datatype binop 25 | = ADD | SUB | MUL | DIV 26 | | LT | LE | EQ | NE | GE | GT 27 | | ANDALSO 28 | 29 | datatype unop 30 | = NEG | NOT 31 | 32 | datatype const 33 | = INTcon of int 34 | 35 | datatype exp 36 | = EXP of exp' * int * int 37 | and exp' 38 | = CONST of const 39 | | VAR of ident 40 | | ARRAY of ident * exp 41 | | ASSIGN of exp * exp 42 | | UNARY of unop * exp 43 | | BINARY of binop * exp * exp 44 | | FCALL of ident * exp list 45 | 46 | (* STATEMENTS *) 47 | 48 | datatype stmt 49 | = STMT of stmt' * int * int 50 | and stmt' 51 | = EMPTY 52 | | EFFECT of exp 53 | | IF of exp * stmt * stmt option 54 | | WHILE of exp * stmt 55 | | RETURN of exp option 56 | | SEQ of stmt * stmt 57 | 58 | (* DECLARATIONS *) 59 | 60 | datatype varDec 61 | = VARDEC of baseTy * declarator 62 | 63 | datatype absDecl 64 | = EMPTYabsdecl 65 | | ARRabsdecl 66 | 67 | datatype absFormal 68 | = ABSDEC of baseTy * absDecl 69 | 70 | datatype topDec 71 | = FUNC of {name: ident, 72 | formals: varDec list, 73 | retTy: baseTy, 74 | locals: varDec list, 75 | body: stmt} 76 | | EXTERN of {name: ident, 77 | formals: varDec list, 78 | retTy: baseTy} 79 | | GLOBAL of varDec 80 | 81 | datatype program 82 | = PROGRAM of {decs: topDec list, 83 | source: Source.source} 84 | 85 | structure IdentDict : ORD_DICT where type Key.ord_key = ident 86 | val makeIdent : string * int * int -> ident 87 | val identName : ident -> string 88 | val identEqual : ident * ident -> bool 89 | 90 | end (* signature ABSYN *) 91 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/absyn/absyn.sml: -------------------------------------------------------------------------------- 1 | (* absyn/absyn.sml *) 2 | 3 | functor AbsynFn(Source : SOURCE) : ABSYN = 4 | struct 5 | 6 | structure Source = Source 7 | 8 | datatype ident 9 | = IDENT of string * int * int 10 | 11 | (* TYPES & DECLARATORS *) 12 | 13 | datatype baseTy 14 | = INTty 15 | | CHARty 16 | | VOIDty 17 | 18 | datatype declarator 19 | = VARdecl of ident 20 | | ARRdecl of ident * int option 21 | 22 | (* EXPRESSIONS *) 23 | 24 | datatype binop 25 | = ADD | SUB | MUL | DIV 26 | | LT | LE | EQ | NE | GE | GT 27 | | ANDALSO 28 | 29 | datatype unop 30 | = NEG | NOT 31 | 32 | datatype const 33 | = INTcon of int 34 | 35 | datatype exp 36 | = EXP of exp' * int * int 37 | and exp' 38 | = CONST of const 39 | | VAR of ident 40 | | ARRAY of ident * exp 41 | | ASSIGN of exp * exp 42 | | UNARY of unop * exp 43 | | BINARY of binop * exp * exp 44 | | FCALL of ident * exp list 45 | 46 | (* STATEMENTS *) 47 | 48 | datatype stmt 49 | = STMT of stmt' * int * int 50 | and stmt' 51 | = EMPTY 52 | | EFFECT of exp 53 | | IF of exp * stmt * stmt option 54 | | WHILE of exp * stmt 55 | | RETURN of exp option 56 | | SEQ of stmt * stmt 57 | 58 | (* DECLARATIONS *) 59 | 60 | datatype varDec 61 | = VARDEC of baseTy * declarator 62 | 63 | datatype absDecl 64 | = EMPTYabsdecl 65 | | ARRabsdecl 66 | 67 | datatype absFormal 68 | = ABSDEC of baseTy * absDecl 69 | 70 | datatype topDec 71 | = FUNC of {name: ident, 72 | formals: varDec list, 73 | retTy: baseTy, 74 | locals: varDec list, 75 | body: stmt} 76 | | EXTERN of {name: ident, 77 | formals: varDec list, 78 | retTy: baseTy} 79 | | GLOBAL of varDec 80 | 81 | datatype program 82 | = PROGRAM of {decs: topDec list, 83 | source: Source.source} 84 | 85 | structure IdentDict = 86 | AADictFn(struct 87 | type ord_key = ident 88 | fun compare(IDENT(s1,_,_), IDENT(s2,_,_)) = 89 | String.compare(s1, s2) 90 | end) 91 | 92 | fun makeIdent(name,left,right) = IDENT(name,left,right) 93 | fun identName(IDENT(name,_,_)) = name 94 | fun identEqual(IDENT(s1,_,_), IDENT(s2,_,_)) = s1=s2 95 | 96 | end (* functor AbsynFn *) 97 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/codegen/assem-print.sig: -------------------------------------------------------------------------------- 1 | (* codegen/assem-print.sig *) 2 | 3 | signature ASSEM_PRINT = 4 | sig 5 | structure Assem : ASSEM 6 | val program : TextIO.outstream * Assem.program -> unit 7 | val fileSuffix : string 8 | end (* signature ASSEM_PRINT *) 9 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/codegen/assem.sig: -------------------------------------------------------------------------------- 1 | (* codegen/assem.sig *) 2 | 3 | signature ASSEM = 4 | sig 5 | type program 6 | end (* signature ASSEM *) 7 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/codegen/codegen.sig: -------------------------------------------------------------------------------- 1 | (* codegen/codegen.sig *) 2 | 3 | signature CODEGEN = 4 | sig 5 | structure RTL : RTL 6 | structure Assem : ASSEM 7 | val program : RTL.program -> Assem.program 8 | end (* signature CODEGEN *) 9 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/codegen/insns.sig: -------------------------------------------------------------------------------- 1 | (* codegen/insns.sig *) 2 | 3 | signature INSNS = 4 | sig 5 | 6 | (* This can be used by a backend to interface 7 | with a graph-colouring register allocator. *) 8 | 9 | type move 10 | type oper 11 | type jump 12 | 13 | type temp = int 14 | type label = string 15 | val moveDefUse : move -> {def: temp, use: temp} 16 | val operDefUse : oper -> {def: temp list, use: temp list} 17 | val jumpDefUse : jump -> {def: temp list, use: temp list} 18 | val jumpTargets: jump -> {labels: label list, fallThrough: bool} 19 | 20 | datatype insn 21 | = LABEL of label 22 | | MOVE of move 23 | | OPER of oper 24 | | JUMP of jump 25 | 26 | end (* signature INSNS *) 27 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/lexer/lexarg.sig: -------------------------------------------------------------------------------- 1 | (* lexer/lexarg.sig *) 2 | 3 | signature LEXARG = 4 | sig 5 | 6 | structure Source: SOURCE 7 | 8 | type pos = int 9 | type lexarg 10 | 11 | val new : string * TextIO.instream -> lexarg * (int -> string) 12 | val newLine : lexarg * pos -> unit 13 | val newTab : lexarg * pos ref * pos -> unit 14 | val leftPos : lexarg -> pos ref 15 | val readPos : lexarg -> pos 16 | val seenErr : lexarg -> bool 17 | val error2 : lexarg -> string * pos * pos -> unit 18 | val source : lexarg -> Source.source 19 | 20 | end (* signature LEXARG *) 21 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/lexer/lexarg.sml: -------------------------------------------------------------------------------- 1 | (* lexer/lexarg.sml *) 2 | 3 | functor LexArgFn(Source : SOURCE) : LEXARG = 4 | struct 5 | 6 | structure Source = Source 7 | 8 | type pos = int 9 | datatype lexarg 10 | = A of { fileName : string, 11 | newLines : int list ref, 12 | thisLine : pos ref, 13 | leftPos : pos ref, 14 | errFlag : bool ref, 15 | readPos : int ref } 16 | 17 | fun new(fileName, is) = 18 | let val readPos = ref 2 (*XXX: ML-Lex*) 19 | fun yyinput n = 20 | let val string = TextIO.inputN(is, n) 21 | val _ = readPos := !readPos + String.size string 22 | in 23 | string 24 | end 25 | val lexarg = 26 | A{fileName = fileName, 27 | newLines = ref [], 28 | thisLine = ref 2, 29 | leftPos = ref 0, 30 | errFlag = ref false, 31 | readPos = readPos} 32 | in 33 | (lexarg,yyinput) 34 | end 35 | 36 | fun newLine(A{newLines,thisLine,...}, pos) = 37 | (newLines := pos :: !newLines; thisLine := pos+1) 38 | 39 | fun newTab(A{thisLine,readPos,...}, yygone, yypos) = 40 | let val lpos = yypos - !thisLine 41 | val incr = 7 - Int.rem(lpos, 8) 42 | in 43 | readPos := !readPos + incr; 44 | yygone := !yygone + incr 45 | end 46 | 47 | fun leftPos(A{leftPos,...}) = leftPos 48 | fun readPos(A{readPos,...}) = !readPos 49 | fun seenErr(A{errFlag,...}) = !errFlag 50 | 51 | fun source(A{fileName,newLines,...}) = 52 | Source.SOURCE{fileName = fileName, newLines = !newLines} 53 | 54 | fun error2 (lexarg as A{errFlag,...}) (msg,left,right) = 55 | (errFlag := true; 56 | Source.sayMsg (source lexarg) ("Error: "^msg, left, right)) 57 | 58 | end (* functor LexArgFn *) 59 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/lexer/uc.lex: -------------------------------------------------------------------------------- 1 | (* lexer/uc.lex *) 2 | 3 | (* parameters for ML-Yacc -- don't change *) 4 | type arg = LexArg.lexarg 5 | type pos = LexArg.pos 6 | type svalue = Tokens.svalue 7 | type ('a,'b) token = ('a,'b) Tokens.token 8 | type lexresult = (svalue,pos) token 9 | 10 | fun eof(lexarg) = 11 | let val pos = LexArg.readPos lexarg 12 | in 13 | (* complete? maybe or maybe not *) 14 | Tokens.EOF(pos, pos) 15 | end 16 | 17 | (* YOUR HELPER FUNCTIONS HERE *) 18 | 19 | (* YOUR HELPER DECLARATIONS BEFORE SECOND "double-percent" *) 20 | (* YOUR TOKENS SPECIFICATION AFTER SECOND "double-percent" *) 21 | (* sorry, but ml-lex doesn't allow comments in the sections below *) 22 | 23 | %% 24 | 25 | %header (functor UCLexFn(structure Tokens : UC_TOKENS 26 | structure LexArg : LEXARG) : ARG_LEXER); 27 | %arg (lexarg); 28 | %full 29 | 30 | %% 31 | 32 | "!=" => 33 | (Tokens.NOTEQ(yypos, yypos+1)); 34 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/main/link.sml: -------------------------------------------------------------------------------- 1 | (* main/link.sml *) 2 | 3 | structure Absyn = AbsynFn(Source); 4 | 5 | structure LexArg = LexArgFn(Source); 6 | 7 | (* These two are for Assignment 1. Remove them afterwards. *) 8 | structure UCLex = 9 | UCLexFn(structure Tokens = FakeTokens 10 | structure LexArg = LexArg 11 | ); 12 | structure FakeParse = 13 | FakeParseFn(structure Absyn = Absyn 14 | structure Lex = UCLex 15 | structure LexArg = LexArg 16 | structure FakeTokens = FakeTokens 17 | ); 18 | 19 | (* These four must be commented out until you start Assignment 2. *) 20 | (* 21 | structure UCLrVals = 22 | UCLrValsFn(structure Token = LrParser.Token 23 | structure Absyn = Absyn 24 | structure LexArg = LexArg 25 | ); 26 | structure UCLex = 27 | UCLexFn(structure Tokens = UCLrVals.Tokens 28 | structure LexArg = LexArg 29 | ); 30 | structure UCParser = 31 | JoinWithArg(structure Lex = UCLex 32 | structure ParserData = UCLrVals.ParserData 33 | structure LrParser = LrParser 34 | ); 35 | structure Parse = 36 | ParseFn(structure Absyn = Absyn 37 | structure Parser = UCParser 38 | structure LexArg = LexArg 39 | ); 40 | *) 41 | 42 | structure AbsynCheck = AbsynCheckFn(Absyn); 43 | structure AbsynPrint = AbsynPrintFn(Absyn); 44 | structure AbsynToRTL = 45 | AbsynToRTLFn(structure Absyn = Absyn 46 | structure RTL = RTL 47 | ); 48 | structure RTLPrint = RTLPrintFn(RTL); 49 | 50 | structure MIPSCodegen = 51 | MIPSCodegenFn(structure RTL = RTL 52 | structure MIPS = MIPS 53 | ); 54 | structure MIPSAssemPrint = 55 | MIPSAssemPrintFn(structure MIPS = MIPS 56 | ); 57 | 58 | structure Main = 59 | MainFn(structure Parse = FakeParse (* XXX: change to Parse after Assignment 1 *) 60 | structure AbsynCheck = AbsynCheck 61 | structure AbsynPrint = AbsynPrint 62 | structure AbsynToRTL = AbsynToRTL 63 | structure RTLPrint = RTLPrint 64 | structure Codegen = MIPSCodegen 65 | structure AssemPrint = MIPSAssemPrint 66 | ); 67 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/main/make.sml: -------------------------------------------------------------------------------- 1 | (* main/make.sml *) 2 | 3 | (*val _ = CM.autoload "smlnj/cm/full.cm";*) 4 | val _ = CM.make "sources.cm"; 5 | (*val _ = CM.make();*) 6 | (*val _ = CM.State.reset();*) 7 | (*val _ = CM.clear();*) 8 | val _ = SMLofNJ.exportFn("ucc", Start.start Main.main); 9 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/main/start.sml: -------------------------------------------------------------------------------- 1 | (* config/start.sml *) 2 | 3 | signature START = 4 | sig 5 | val start: (string list -> unit) -> string * string list -> OS.Process.status 6 | end (* signature START *) 7 | 8 | structure Start : START = 9 | struct 10 | 11 | fun sayErr msg = TextIO.output(TextIO.stdErr, msg) 12 | 13 | exception Interrupt 14 | 15 | (* This function applies operation to argument. If it handles an interrupt 16 | * signal (Control-C), it raises the exception Interrupt. Example: 17 | * (handleInterrupt(foo,x)) handle Interrupt => print "Bang!\n" 18 | *) 19 | fun handleInterrupt(operation: 'a -> unit, argument: 'a) = 20 | let exception Done 21 | val oldHandler = Signals.inqHandler(Signals.sigINT) 22 | fun resetHandler() = 23 | Signals.setHandler(Signals.sigINT, oldHandler) 24 | in (SMLofNJ.Cont.callcc(fn k => 25 | (Signals.setHandler(Signals.sigINT, Signals.HANDLER(fn _ => k)); 26 | operation argument; 27 | raise Done)); 28 | raise Interrupt) 29 | handle Done => (resetHandler(); ()) 30 | | exn => (resetHandler(); raise exn) 31 | end 32 | 33 | fun start main (arg0,argv) = 34 | (handleInterrupt(main, argv); OS.Process.success) 35 | handle Interrupt => (sayErr "Interrupt\n"; OS.Process.failure) 36 | | exn => (sayErr "Error: "; sayErr(General.exnMessage exn); 37 | sayErr "\n"; OS.Process.failure) 38 | 39 | end (* structure Start *) 40 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/mips/mips-assem-print.sml: -------------------------------------------------------------------------------- 1 | (* mips/mips-assem-print.sml *) 2 | 3 | functor MIPSAssemPrintFn(structure MIPS : MIPS 4 | ) : ASSEM_PRINT = 5 | struct 6 | 7 | structure Assem = MIPS 8 | 9 | fun program(os, p) = MIPS.print_program(p, os) 10 | 11 | val fileSuffix = ".s" 12 | 13 | end (* functor MIPSAssemPrintFn *) 14 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/mips/mips-codegen.sml: -------------------------------------------------------------------------------- 1 | (* mips/mips-codegen.sml *) 2 | 3 | functor MIPSCodegenFn(structure RTL : RTL 4 | structure MIPS : MIPS 5 | (* YOUR HELPER MODULES HERE *) 6 | ) : CODEGEN = 7 | struct 8 | 9 | structure RTL = RTL 10 | structure Assem = MIPS 11 | 12 | fun program p = [] (* XXX: REPLACE WITH YOUR CODE *) 13 | 14 | end (* functor MIPSCodegenFn *) 15 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/parser/fake-parse.sml: -------------------------------------------------------------------------------- 1 | (* parser/fake-parse.sml *) 2 | (* This is only to be used for Assignment 1. *) 3 | 4 | signature UC_TOKENS = 5 | sig 6 | type svalue (*= unit*) 7 | datatype ('a,'b) token 8 | = EOF of 'b * 'b 9 | | NOTEQ of 'b * 'b 10 | (* YOU NEED TO ADD REMAINING TOKENS HERE FOR ASSIGNMENT 1 *) 11 | 12 | val printToken: (svalue,int) token -> unit 13 | 14 | end (* signature UC_TOKENS *) 15 | 16 | structure FakeTokens : UC_TOKENS = 17 | struct 18 | type svalue = unit 19 | datatype ('a,'b) token 20 | = EOF of 'b * 'b 21 | | NOTEQ of 'b * 'b 22 | (* YOU NEED TO ADD REMAINING TOKENS HERE FOR ASSIGNMENT 1 *) 23 | 24 | fun printToken(t) = () (* XXX: YOUR CODE *) 25 | end (* structure Tokens *) 26 | 27 | functor FakeParseFn(structure Absyn : ABSYN 28 | structure Lex : ARG_LEXER 29 | where type UserDeclarations.pos = int 30 | structure LexArg : LEXARG 31 | structure FakeTokens : UC_TOKENS 32 | sharing type Lex.UserDeclarations.token = FakeTokens.token 33 | sharing type Lex.UserDeclarations.svalue = FakeTokens.svalue 34 | sharing type LexArg.lexarg = Lex.UserDeclarations.arg 35 | sharing Absyn.Source = LexArg.Source 36 | ) : PARSE = 37 | struct 38 | 39 | structure Absyn = Absyn 40 | 41 | exception ParseError 42 | 43 | fun processTokens(lexer) = () (* XXX: YOUR CODE *) 44 | 45 | fun program file = 46 | let val is = TextIO.openIn file 47 | in 48 | (let val (lexarg,inputf) = LexArg.new(file, is) 49 | val lexer = Lex.makeLexer inputf lexarg 50 | val _ = processTokens(lexer) 51 | in 52 | if LexArg.seenErr lexarg then raise ParseError 53 | else 54 | let val _ = TextIO.closeIn is 55 | in 56 | Absyn.PROGRAM{decs=[], source=LexArg.Source.dummy} 57 | end 58 | end) handle e => (TextIO.closeIn is; raise e) 59 | end 60 | 61 | end (* functor FakeParseFn *) 62 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/parser/parse.sig: -------------------------------------------------------------------------------- 1 | (* parser/parse.sig *) 2 | 3 | signature PARSE = 4 | sig 5 | 6 | structure Absyn : ABSYN 7 | val program : string -> Absyn.program 8 | 9 | end (* signature PARSE *) 10 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/parser/parse.sml: -------------------------------------------------------------------------------- 1 | (* parser/parse.sml *) 2 | 3 | functor ParseFn(structure Absyn : ABSYN 4 | structure Parser : ARG_PARSER 5 | where type arg = unit 6 | and type pos = int 7 | structure LexArg : LEXARG 8 | sharing type Parser.result = Absyn.program 9 | sharing type Parser.lexarg = LexArg.lexarg 10 | sharing Absyn.Source = LexArg.Source 11 | ) : PARSE = 12 | struct 13 | structure Absyn = Absyn 14 | 15 | fun program file = 16 | let val is = TextIO.openIn file 17 | in 18 | (let val (lexarg,inputf) = LexArg.new(file, is) 19 | val lexer = Parser.makeLexer inputf lexarg 20 | val (result,_) = Parser.parse(0,lexer,LexArg.error2 lexarg,()) 21 | in 22 | if LexArg.seenErr lexarg then raise Parser.ParseError 23 | else 24 | let val _ = TextIO.closeIn is 25 | val Absyn.PROGRAM{decs,...} = result 26 | in 27 | Absyn.PROGRAM{decs=decs,source=LexArg.source lexarg} 28 | end 29 | end) handle e => (TextIO.closeIn is; raise e) 30 | end 31 | 32 | end (* functor ParseFn *) 33 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/rtl/absyn-to-rtl.sml: -------------------------------------------------------------------------------- 1 | (* rtl/absyn-to-rtl.sml *) 2 | 3 | signature ABSYN_TO_RTL = 4 | sig 5 | structure Absyn : ABSYN 6 | structure RTL : RTL 7 | val program : Absyn.program -> RTL.program 8 | end (* signature ABSYN_TO_RTL *) 9 | 10 | functor AbsynToRTLFn(structure Absyn : ABSYN 11 | structure RTL : RTL 12 | ) : ABSYN_TO_RTL = 13 | struct 14 | 15 | structure Absyn = Absyn 16 | structure RTL = RTL 17 | 18 | structure IdentDict = Absyn.IdentDict 19 | 20 | fun procLabel id = "P" ^ Absyn.identName id 21 | fun varLabel id = "V" ^ Absyn.identName id 22 | 23 | exception AbsynToRTL 24 | fun bug msg = 25 | (TextIO.output(TextIO.stdErr, "Compiler error: "^msg^"\n"); 26 | raise AbsynToRTL) 27 | 28 | (* XXX: REPLACE WITH YOUR CODE *) 29 | 30 | fun program(Absyn.PROGRAM{decs,...}) = 31 | RTL.PROGRAM([]) 32 | 33 | end (* functor AbsynToRTLFn *) 34 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/rtl/rtl.sig: -------------------------------------------------------------------------------- 1 | (* rtl/rtl.sig *) 2 | 3 | signature RTL = 4 | sig 5 | 6 | datatype ty (* for memory load/store operations *) 7 | = BYTE (* char *) 8 | | LONG (* int or pointer *) 9 | 10 | type temp = int (* pseudo register *) 11 | type label = string 12 | 13 | val RV : temp (* temp for return value *) 14 | val FP : temp (* frame pointer temp, for storage of local arrays *) 15 | 16 | datatype relop 17 | = LT | LE | EQ | NE | GE | GT 18 | 19 | datatype unop 20 | = LOAD of ty (* load value of type 'ty' from address in operand *) 21 | 22 | datatype binop 23 | = ADD | SUB | MUL | DIV 24 | 25 | datatype expr 26 | (* moving values into the result temp *) 27 | = TEMP of temp 28 | | ICON of int 29 | | LABREF of label 30 | (* unary operators *) 31 | | UNARY of unop * temp 32 | (* binary operators *) 33 | | BINARY of binop * temp * temp 34 | 35 | datatype insn 36 | (* control flow *) 37 | = LABDEF of label 38 | | JUMP of label 39 | | CJUMP of relop * temp * temp * label 40 | (* stores to memory *) 41 | | STORE of ty * temp * temp 42 | (* simple expression evaluation *) 43 | | EVAL of temp * expr 44 | (* function calls: could be expr but result temp is optional *) 45 | | CALL of temp option * label * temp list 46 | 47 | datatype dec 48 | = PROC of {label: label, formals: temp list, locals: temp list, 49 | frameSize: int, insns: insn list} 50 | | DATA of {label: label, size: int} 51 | 52 | datatype program 53 | = PROGRAM of dec list 54 | 55 | val newLabel: unit -> label 56 | val newTemp: unit -> temp 57 | 58 | val sizeof: ty -> int 59 | 60 | end (* signature RTL *) 61 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/rtl/rtl.sml: -------------------------------------------------------------------------------- 1 | (* rtl/rtl.sml *) 2 | 3 | structure RTL : RTL = 4 | struct 5 | 6 | datatype ty (* for memory load/store operations *) 7 | = BYTE (* char *) 8 | | LONG (* int or pointer *) 9 | 10 | type temp = int (* pseudo register *) 11 | type label = string 12 | 13 | val RV = 0 (* temp for return value *) 14 | val FP = 1 (* frame pointer temp, for storage of local arrays *) 15 | 16 | datatype relop 17 | = LT | LE | EQ | NE | GE | GT 18 | 19 | datatype unop 20 | = LOAD of ty (* load value of type 'ty' from address in operand *) 21 | 22 | datatype binop 23 | = ADD | SUB | MUL | DIV 24 | 25 | datatype expr 26 | (* moving values into the result temp *) 27 | = TEMP of temp 28 | | ICON of int 29 | | LABREF of label 30 | (* unary operators *) 31 | | UNARY of unop * temp 32 | (* binary operators *) 33 | | BINARY of binop * temp * temp 34 | 35 | datatype insn 36 | (* control flow *) 37 | = LABDEF of label 38 | | JUMP of label 39 | | CJUMP of relop * temp * temp * label 40 | (* stores to memory *) 41 | | STORE of ty * temp * temp 42 | (* simple expression evaluation *) 43 | | EVAL of temp * expr 44 | (* function calls: could be expr but result temp is optional *) 45 | | CALL of temp option * label * temp list 46 | 47 | datatype dec 48 | = PROC of {label: label, formals: temp list, locals: temp list, 49 | frameSize: int, insns: insn list} 50 | | DATA of {label: label, size: int} 51 | 52 | datatype program 53 | = PROGRAM of dec list 54 | 55 | fun tick counter = 56 | let val i = !counter + 1 57 | val _ = counter := i 58 | in 59 | i 60 | end 61 | 62 | val labCounter = ref 99 63 | fun newLabel() = "L" ^ Int.toString(tick labCounter) 64 | 65 | val tempCounter = ref 1 66 | fun newTemp() = tick tempCounter 67 | 68 | fun sizeof(BYTE) = 1 (* per definition *) 69 | | sizeof(LONG) = 4 (* ok for 32-bitters *) 70 | 71 | end (* structure RTL *) 72 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/sources.cm: -------------------------------------------------------------------------------- 1 | (* sources.cm -- CM source list for the Micro-C compiler UCC *) 2 | (* designed for use with SML/NJ 110.59 *) 3 | 4 | Group 5 | is 6 | 7 | $/basis.cm 8 | $/smlnj-lib.cm 9 | $/ml-yacc-lib.cm 10 | 11 | util/source.sig 12 | util/source.sml 13 | util/ord-dict-sig.sml 14 | util/aa-dict-fn.sml 15 | 16 | absyn/absyn.sig 17 | absyn/absyn.sml 18 | absyn/absyn-check.sml 19 | absyn/absyn-print.sml 20 | 21 | lexer/lexarg.sig 22 | lexer/lexarg.sml 23 | (*parser/uc.grm*) (* uncomment after assignment 1 *) 24 | lexer/uc.lex 25 | parser/parse.sig 26 | parser/parse.sml 27 | parser/fake-parse.sml (* comment out when uc.grm is working *) 28 | 29 | rtl/rtl.sig 30 | rtl/rtl.sml 31 | rtl/absyn-to-rtl.sml 32 | rtl/rtl-print.sml 33 | 34 | codegen/insns.sig 35 | codegen/assem.sig 36 | codegen/codegen.sig 37 | codegen/assem-print.sig 38 | 39 | mips/mips-codegen.sml 40 | mips/mips-assem-print.sml 41 | mips/mips.sig 42 | mips/mips.sml 43 | 44 | main/main.sml 45 | main/link.sml 46 | main/start.sml 47 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/ucc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ARCH=unknown 3 | OPSYS=unknown 4 | case `uname -s` in 5 | SunOS) case `uname -r` in 6 | 5.*) OPSYS=solaris;; 7 | esac 8 | case `uname -m` in 9 | sun4*) ARCH=sparc;; 10 | i86pc) ARCH=x86;; 11 | esac;; 12 | Linux) OPSYS=linux 13 | case `uname -m` in 14 | i[3456]86) ARCH=x86;; 15 | esac;; 16 | esac 17 | exec sml @SMLload=ucc.$ARCH-$OPSYS $* 18 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/util/ord-dict-sig.sml: -------------------------------------------------------------------------------- 1 | (* util/ord-dict-sig.sml *) 2 | 3 | signature ORD_DICT = 4 | sig 5 | 6 | structure Key : ORD_KEY 7 | 8 | type 'a dict 9 | val empty : 'a dict 10 | val insert : 'a dict * Key.ord_key * 'a -> 'a dict 11 | val find' : 'a dict * Key.ord_key -> (Key.ord_key * 'a) option 12 | val find : 'a dict * Key.ord_key -> 'a option 13 | val plus : 'a dict * 'a dict -> 'a dict 14 | val fold : (Key.ord_key * 'a * 'b -> 'b) * 'b * 'a dict -> 'b 15 | 16 | end (* signature ORD_DICT *) 17 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/util/source.sig: -------------------------------------------------------------------------------- 1 | (* util/source.sig *) 2 | 3 | signature SOURCE = 4 | sig 5 | 6 | datatype source 7 | = SOURCE of 8 | { fileName: string, 9 | newLines: int list } (* _descending_ order *) 10 | 11 | val dummy : source 12 | val sayMsg : source -> string * int * int -> unit 13 | 14 | end (* signature SOURCE *) 15 | -------------------------------------------------------------------------------- /_resources_/ucc-smlnj-student-2012-01-13/util/source.sml: -------------------------------------------------------------------------------- 1 | (* util/source.sml *) 2 | 3 | structure Source : SOURCE = 4 | struct 5 | 6 | datatype source 7 | = SOURCE of 8 | { fileName: string, 9 | newLines: int list } (* _descending_ order *) 10 | 11 | val dummy = SOURCE{fileName="", newLines=[]} 12 | 13 | (* The pos of an imaginary newline before a file's very 14 | * first character. This is necessary to adjust for the 15 | * weird notion of ML-Lex that the first character has 16 | * position 2. Not 0 or 1, but 2. 17 | * XXX: THIS WILL BREAK IF ML-LEX IS FIXED 18 | *) 19 | val startPos = 1 20 | 21 | fun lookup(newLines, pos) = 22 | let fun loop([], _) = {line = 1, column = pos - startPos} 23 | | loop(newLine::newLines, line) = 24 | if pos > newLine then {line = line, column = pos - newLine} 25 | else loop(newLines, line - 1) 26 | in 27 | loop(newLines, 1 + List.length newLines) 28 | end 29 | 30 | fun sayErr s = TextIO.output(TextIO.stdErr, s) 31 | fun sayErr1 c = TextIO.output1(TextIO.stdErr, c) 32 | 33 | fun sayFile file = (sayErr file; sayErr1 #":") 34 | 35 | fun sayPos(newLines, pos) = 36 | let val {line,column} = lookup(newLines, pos) 37 | in 38 | sayErr(Int.toString line); 39 | sayErr1 #"."; 40 | sayErr(Int.toString column) 41 | end 42 | 43 | fun sayMsg (SOURCE{fileName,newLines}) (msg,leftPos,rightPos) = 44 | (sayFile fileName; 45 | sayPos(newLines, leftPos); 46 | sayErr1 #"-"; 47 | sayPos(newLines, rightPos); 48 | sayErr1 #" "; 49 | sayErr msg; 50 | sayErr1 #"\n") 51 | 52 | end (* structure Source *) 53 | -------------------------------------------------------------------------------- /ast/astutil/astutil.go: -------------------------------------------------------------------------------- 1 | // Package astutil implements utility functions for handling parse trees. 2 | package astutil 3 | 4 | import "github.com/mewmew/uc/ast" 5 | 6 | // IsDef reports whether the given declaration is a definition. 7 | func IsDef(decl ast.Decl) bool { 8 | if _, ok := decl.(*ast.VarDecl); ok { 9 | return true 10 | } 11 | return decl.Value() != nil 12 | } 13 | -------------------------------------------------------------------------------- /ast/astx/type.go: -------------------------------------------------------------------------------- 1 | package astx 2 | 3 | import ( 4 | "github.com/mewkiz/pkg/errutil" 5 | "github.com/mewmew/uc/ast" 6 | gocctoken "github.com/mewmew/uc/gocc/token" 7 | ) 8 | 9 | // NewType returns a new type of µC. 10 | func NewType(typ interface{}) (ast.Type, error) { 11 | if typ, ok := typ.(ast.Type); ok { 12 | return typ, nil 13 | } 14 | return nil, errutil.Newf("invalid type; expected ast.Type, got %T", typ) 15 | } 16 | 17 | // NewArrayType returns a new array type based on the given element type and 18 | // length. 19 | func NewArrayType(elem, lbracket, length, rbracket interface{}) (*ast.ArrayType, error) { 20 | len, ok := length.(int) 21 | if !ok { 22 | return nil, errutil.Newf("invalid array length type; %T", length) 23 | } 24 | 25 | var lbrack, rbrack int 26 | switch lbracket := lbracket.(type) { 27 | case *gocctoken.Token: 28 | lbrack = lbracket.Offset 29 | case int: 30 | lbrack = lbracket 31 | default: 32 | return nil, errutil.Newf("invalid left-bracket type; expectd *gocctoken.Token or int, got %T", lbracket) 33 | } 34 | switch rbracket := rbracket.(type) { 35 | case *gocctoken.Token: 36 | rbrack = rbracket.Offset 37 | case int: 38 | rbrack = rbracket 39 | default: 40 | return nil, errutil.Newf("invalid right-bracket type; expectd *gocctoken.Token or int, got %T", rbracket) 41 | } 42 | 43 | elemType, err := NewType(elem) 44 | if err != nil { 45 | return nil, errutil.Newf("invalid array element type; %v", err) 46 | } 47 | return &ast.ArrayType{Elem: elemType, Lbracket: lbrack, Len: len, Rbracket: rbrack}, nil 48 | } 49 | -------------------------------------------------------------------------------- /ast/types.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/mewmew/uc/types" 7 | ) 8 | 9 | // newType returns a new type equivalent to the given type node. 10 | func newType(n Node) types.Type { 11 | switch n := n.(type) { 12 | case *ArrayType: 13 | return &types.Array{Elem: newType(n.Elem), Len: n.Len} 14 | case *FuncType: 15 | params := make([]*types.Field, len(n.Params)) 16 | for i := range n.Params { 17 | params[i] = newField(n.Params[i]) 18 | } 19 | return &types.Func{Result: newType(n.Result), Params: params} 20 | case *Ident: 21 | if n.Decl == nil { 22 | return newBasic(n) 23 | } 24 | return n.Decl.Type() 25 | default: 26 | panic(fmt.Sprintf("support for type %T not yet implemented", n)) 27 | } 28 | } 29 | 30 | // newField returns a new field type equivalent to the given field node. 31 | func newField(decl *VarDecl) *types.Field { 32 | typ := &types.Field{Type: decl.Type()} 33 | if decl.VarName != nil { 34 | typ.Name = decl.VarName.Name 35 | } 36 | return typ 37 | } 38 | 39 | // universePos specifies a pseudo-position used for identifiers declared in the 40 | // universe scope. 41 | const universePos = -1 42 | 43 | // newBasic returns a new basic type equivalent to the given identifier. 44 | func newBasic(ident *Ident) types.Type { 45 | // TODO: Check if we may come up with a cleaner solution. At least, this 46 | // works for now. 47 | switch ident.Name { 48 | case "char": 49 | charIdent := &Ident{NamePos: universePos, Name: "char"} 50 | charType := &types.Basic{Kind: types.Char} 51 | charDecl := &TypeDef{DeclType: charIdent, TypeName: charIdent, Val: charType} 52 | charIdent.Decl = charDecl 53 | ident.Decl = charDecl 54 | return charType 55 | case "int": 56 | intIdent := &Ident{NamePos: universePos, Name: "int"} 57 | intType := &types.Basic{Kind: types.Int} 58 | intDecl := &TypeDef{DeclType: intIdent, TypeName: intIdent, Val: intType} 59 | intIdent.Decl = intDecl 60 | ident.Decl = intDecl 61 | return intType 62 | case "void": 63 | voidIdent := &Ident{NamePos: universePos, Name: "void"} 64 | voidType := &types.Basic{Kind: types.Void} 65 | voidDecl := &TypeDef{DeclType: voidIdent, TypeName: voidIdent, Val: voidType} 66 | voidIdent.Decl = voidDecl 67 | ident.Decl = voidDecl 68 | return voidType 69 | default: 70 | panic(fmt.Sprintf("support for user-defined basic type %q not yet fully supported", ident.Name)) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /cmd/internal/debug/debug.go: -------------------------------------------------------------------------------- 1 | // Package debug implements lexer and parser debugging utility functions. 2 | package debug 3 | 4 | import ( 5 | "fmt" 6 | 7 | "github.com/mewmew/uc/gocc/parser" 8 | "github.com/mewmew/uc/gocc/token" 9 | ) 10 | 11 | // A Scanner wraps a parser.Scanner to produce debug output while scanning. 12 | type Scanner struct { 13 | s parser.Scanner 14 | } 15 | 16 | // NewScanner returns a debug scanner which produces debug output while scanner 17 | // from s. 18 | func NewScanner(s parser.Scanner) parser.Scanner { 19 | return &Scanner{s: s} 20 | } 21 | 22 | // Scan scans from the underlying scanner and prints scanned tokens to standard 23 | // output. 24 | func (ds *Scanner) Scan() *token.Token { 25 | tok := ds.s.Scan() 26 | fmt.Println("pos:", tok.Pos.Offset) 27 | fmt.Println("typ:", tok.Type) 28 | fmt.Println("lit:", string(tok.Lit)) 29 | fmt.Println() 30 | return tok 31 | } 32 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -lt 1 ]; then 3 | echo "Usage: compile FILE.c" 4 | exit 1 5 | fi 6 | f=$1 7 | uclang -o a.ll "${f}" 8 | if [ $? -ne 0 ]; then 9 | echo "FAILURE: ${f}" 10 | exit 1 11 | fi 12 | llvm-link -S -o out.ll a.ll testdata/uc.ll 13 | echo "SUCCESS: ${f}" 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mewmew/uc 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/davecgh/go-spew v1.1.1 7 | github.com/kr/pretty v0.2.1 8 | github.com/llir/llvm v0.3.3 9 | github.com/mewkiz/pkg v0.0.0-20210112042322-0b163ae15d52 10 | golang.org/x/mod v0.4.2 // indirect 11 | golang.org/x/sys v0.0.0-20210324051608-47abb6519492 // indirect 12 | golang.org/x/text v0.3.5 13 | golang.org/x/tools v0.1.0 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /gocc/Makefile: -------------------------------------------------------------------------------- 1 | gen: uc.bnf 2 | gocc $< 3 | find . -type f -name '*.go' | xargs goimports -w 4 | 5 | debug_lexer: uc.bnf 6 | gocc -debug_lexer -v $< 7 | find . -type f -name '*.go' | xargs goimports -w 8 | 9 | debug_parser: uc.bnf 10 | gocc -debug_parser -v $< 11 | find . -type f -name '*.go' | xargs goimports -w 12 | 13 | clean: 14 | rm -f errors/errors.go 15 | rm -f lexer/acttab.go 16 | rm -f lexer/lexer.go 17 | rm -f lexer/transitiontable.go 18 | rm -f parser/action.go 19 | rm -f parser/actiontable.go 20 | rm -f parser/gototable.go 21 | rm -f parser/parser.go 22 | rm -f parser/productionstable.go 23 | rm -f token/token.go 24 | rm -f util/litconv.go 25 | rm -f util/rune.go 26 | -rmdir --ignore-fail-on-non-empty errors 27 | -rmdir --ignore-fail-on-non-empty lexer 28 | -rmdir --ignore-fail-on-non-empty parser 29 | -rmdir --ignore-fail-on-non-empty token 30 | -rmdir --ignore-fail-on-non-empty util 31 | rm -f terminals.txt LR1_conflicts.txt LR1_sets.txt first.txt lexer_sets.txt 32 | 33 | .PHONY: gen debug_lexer debug_parser clean 34 | -------------------------------------------------------------------------------- /gocc/errors/errors.go: -------------------------------------------------------------------------------- 1 | // generated by gocc; DO NOT EDIT. 2 | 3 | package errors 4 | 5 | import ( 6 | "bytes" 7 | "fmt" 8 | 9 | "github.com/mewmew/uc/gocc/token" 10 | ) 11 | 12 | type ErrorSymbol interface { 13 | } 14 | 15 | type Error struct { 16 | Err error 17 | ErrorToken *token.Token 18 | ErrorSymbols []ErrorSymbol 19 | ExpectedTokens []string 20 | StackTop int 21 | } 22 | 23 | func (E *Error) String() string { 24 | w := new(bytes.Buffer) 25 | fmt.Fprintf(w, "Error") 26 | if E.Err != nil { 27 | fmt.Fprintf(w, " %s\n", E.Err) 28 | } else { 29 | fmt.Fprintf(w, "\n") 30 | } 31 | fmt.Fprintf(w, "Token: type=%d, lit=%s\n", E.ErrorToken.Type, E.ErrorToken.Lit) 32 | fmt.Fprintf(w, "Pos: offset=%d, line=%d, column=%d\n", E.ErrorToken.Pos.Offset, E.ErrorToken.Pos.Line, E.ErrorToken.Pos.Column) 33 | fmt.Fprintf(w, "Expected one of: ") 34 | for _, sym := range E.ExpectedTokens { 35 | fmt.Fprintf(w, "%s ", sym) 36 | } 37 | fmt.Fprintf(w, "ErrorSymbol:\n") 38 | for _, sym := range E.ErrorSymbols { 39 | fmt.Fprintf(w, "%v\n", sym) 40 | } 41 | return w.String() 42 | } 43 | 44 | func (e *Error) Error() string { 45 | w := new(bytes.Buffer) 46 | fmt.Fprintf(w, "Error in S%d: %s, %s", e.StackTop, token.TokMap.TokenString(e.ErrorToken), e.ErrorToken.Pos.String()) 47 | if e.Err != nil { 48 | fmt.Fprintf(w, e.Err.Error()) 49 | } else { 50 | fmt.Fprintf(w, ", expected one of: ") 51 | for _, expected := range e.ExpectedTokens { 52 | fmt.Fprintf(w, "%s ", expected) 53 | } 54 | } 55 | return w.String() 56 | } 57 | -------------------------------------------------------------------------------- /gocc/lexer/lexer_test.go: -------------------------------------------------------------------------------- 1 | package lexer_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "testing" 6 | 7 | "github.com/mewmew/uc/gocc/lexer" 8 | "github.com/mewmew/uc/gocc/token" 9 | ) 10 | 11 | func BenchmarkLexer(b *testing.B) { 12 | buf, err := ioutil.ReadFile("../../testdata/noisy/advanced/eval.c") 13 | if err != nil { 14 | b.Fatal(err) 15 | } 16 | b.SetBytes(int64(len(buf))) 17 | for i := 0; i < b.N; i++ { 18 | l := lexer.NewLexer(buf) 19 | for { 20 | tok := l.Scan() 21 | if tok.Type == token.EOF { 22 | break 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gocc/parser/action.go: -------------------------------------------------------------------------------- 1 | // generated by gocc; DO NOT EDIT. 2 | 3 | package parser 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | type action interface { 10 | act() 11 | String() string 12 | } 13 | 14 | type ( 15 | accept bool 16 | shift int // value is next state index 17 | reduce int // value is production index 18 | ) 19 | 20 | func (this accept) act() {} 21 | func (this shift) act() {} 22 | func (this reduce) act() {} 23 | 24 | func (this accept) Equal(that action) bool { 25 | if _, ok := that.(accept); ok { 26 | return true 27 | } 28 | return false 29 | } 30 | 31 | func (this reduce) Equal(that action) bool { 32 | that1, ok := that.(reduce) 33 | if !ok { 34 | return false 35 | } 36 | return this == that1 37 | } 38 | 39 | func (this shift) Equal(that action) bool { 40 | that1, ok := that.(shift) 41 | if !ok { 42 | return false 43 | } 44 | return this == that1 45 | } 46 | 47 | func (this accept) String() string { return "accept(0)" } 48 | func (this shift) String() string { return fmt.Sprintf("shift:%d", this) } 49 | func (this reduce) String() string { 50 | return fmt.Sprintf("reduce:%d(%s)", this, productionsTable[this].String) 51 | } 52 | -------------------------------------------------------------------------------- /gocc/parser/error.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | 7 | "github.com/mewmew/uc/gocc/errors" 8 | ) 9 | 10 | // NewError returns a user-friendly parse error. 11 | func NewError(err *errors.Error) error { 12 | if err.Err != nil { 13 | return err.Err 14 | } 15 | // TODO: Add line:col positional tracking. 16 | var expected []string 17 | for _, tok := range err.ExpectedTokens { 18 | if tok == "error" { 19 | // Remove "error" production rule from the set of expected tokens. 20 | continue 21 | } 22 | expected = append(expected, tok) 23 | } 24 | sort.Strings(expected) 25 | return fmt.Errorf("%d: unexpected %q, expected %q", err.ErrorToken.Pos.Offset, string(err.ErrorToken.Lit), expected) 26 | } 27 | -------------------------------------------------------------------------------- /gocc/scanner/scanner.go: -------------------------------------------------------------------------------- 1 | // Package scanner implements a lexer which satifies the Gocc Scanner interface. 2 | package scanner 3 | 4 | import ( 5 | "bytes" 6 | "io" 7 | "io/ioutil" 8 | "strings" 9 | 10 | "github.com/mewkiz/pkg/errutil" 11 | "github.com/mewmew/uc/gocc/lexer" 12 | "github.com/mewmew/uc/gocc/token" 13 | ) 14 | 15 | // Scanner represents the lexer interface used by the Gocc parser. 16 | type Scanner interface { 17 | // Scan lexes and returns the next token of the source input. 18 | Scan() *token.Token 19 | } 20 | 21 | const ( 22 | // whitespace specifies the white-space characters: space (0x20), horizontal 23 | // tab (0x09), new line (line-feed (0x0A) or carriage-return (0x0D)), 24 | // vertical tab (0x0B), and form-feed (0x0C) (§6.4). 25 | // 26 | // Note: Even though not explicitly mentioned in the C11 specification, 27 | // carriage return (0x0D) is treated as a white-space character by the lexer, 28 | // as it is part of the CRLF newline character sequence. 29 | whitespace = " \t\n\v\f\r" 30 | ) 31 | 32 | // New returns a new scanner lexing from r. 33 | func New(r io.Reader) (Scanner, error) { 34 | input, err := ioutil.ReadAll(r) 35 | if err != nil { 36 | return nil, errutil.Err(err) 37 | } 38 | return NewFromBytes(input), nil 39 | } 40 | 41 | // Open returns a new scanner lexing from path. 42 | func Open(path string) (Scanner, error) { 43 | input, err := ioutil.ReadFile(path) 44 | if err != nil { 45 | return nil, errutil.Err(err) 46 | } 47 | return NewFromBytes(input), nil 48 | } 49 | 50 | // NewFromString returns a new scanner lexing from input. 51 | func NewFromString(input string) Scanner { 52 | return NewFromBytes([]byte(input)) 53 | } 54 | 55 | // NewFromBytes returns a new scanner lexing from input. 56 | func NewFromBytes(input []byte) Scanner { 57 | // Append new line to files not ending with new line. 58 | appendNewLine := false 59 | lastNewLine := bytes.LastIndexByte(input, '\n') 60 | for _, r := range string(input[lastNewLine+1:]) { 61 | if !strings.ContainsRune(whitespace, r) { 62 | // Non-whitespace character located after the last new line character. 63 | appendNewLine = true 64 | break 65 | } 66 | } 67 | if appendNewLine { 68 | input = append(input, '\n') 69 | } 70 | 71 | return lexer.NewLexer(input) 72 | } 73 | -------------------------------------------------------------------------------- /gocc/token/token.go: -------------------------------------------------------------------------------- 1 | // generated by gocc; DO NOT EDIT. 2 | 3 | package token 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | type Token struct { 10 | Type 11 | Lit []byte 12 | Pos 13 | } 14 | 15 | type Type int 16 | 17 | const ( 18 | INVALID Type = iota 19 | EOF 20 | ) 21 | 22 | type Pos struct { 23 | Offset int 24 | Line int 25 | Column int 26 | } 27 | 28 | func (this Pos) String() string { 29 | return fmt.Sprintf("Pos(offset=%d, line=%d, column=%d)", this.Offset, this.Line, this.Column) 30 | } 31 | 32 | type TokenMap struct { 33 | typeMap []string 34 | idMap map[string]Type 35 | } 36 | 37 | func (this TokenMap) Id(tok Type) string { 38 | if int(tok) < len(this.typeMap) { 39 | return this.typeMap[tok] 40 | } 41 | return "unknown" 42 | } 43 | 44 | func (this TokenMap) Type(tok string) Type { 45 | if typ, exist := this.idMap[tok]; exist { 46 | return typ 47 | } 48 | return INVALID 49 | } 50 | 51 | func (this TokenMap) TokenString(tok *Token) string { 52 | //TODO: refactor to print pos & token string properly 53 | return fmt.Sprintf("%s(%d,%s)", this.Id(tok.Type), tok.Type, tok.Lit) 54 | } 55 | 56 | func (this TokenMap) StringType(typ Type) string { 57 | return fmt.Sprintf("%s(%d)", this.Id(typ), typ) 58 | } 59 | 60 | var TokMap = TokenMap{ 61 | typeMap: []string{ 62 | "INVALID", 63 | "$", 64 | "empty", 65 | ";", 66 | "ident", 67 | "(", 68 | ")", 69 | "[", 70 | "]", 71 | "int_lit", 72 | "char_lit", 73 | "typedef", 74 | ",", 75 | "return", 76 | "{", 77 | "}", 78 | "if", 79 | "else", 80 | "while", 81 | "=", 82 | "&&", 83 | "==", 84 | "!=", 85 | "<", 86 | ">", 87 | "<=", 88 | ">=", 89 | "+", 90 | "-", 91 | "*", 92 | "/", 93 | "!", 94 | }, 95 | 96 | idMap: map[string]Type{ 97 | "INVALID": 0, 98 | "$": 1, 99 | "empty": 2, 100 | ";": 3, 101 | "ident": 4, 102 | "(": 5, 103 | ")": 6, 104 | "[": 7, 105 | "]": 8, 106 | "int_lit": 9, 107 | "char_lit": 10, 108 | "typedef": 11, 109 | ",": 12, 110 | "return": 13, 111 | "{": 14, 112 | "}": 15, 113 | "if": 16, 114 | "else": 17, 115 | "while": 18, 116 | "=": 19, 117 | "&&": 20, 118 | "==": 21, 119 | "!=": 22, 120 | "<": 23, 121 | ">": 24, 122 | "<=": 25, 123 | ">=": 26, 124 | "+": 27, 125 | "-": 28, 126 | "*": 29, 127 | "/": 30, 128 | "!": 31, 129 | }, 130 | } 131 | -------------------------------------------------------------------------------- /gocc/util/rune.go: -------------------------------------------------------------------------------- 1 | // generated by gocc; DO NOT EDIT. 2 | 3 | //Copyright 2013 Vastech SA (PTY) LTD 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | package util 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | func RuneToString(r rune) string { 24 | if r >= 0x20 && r < 0x7f { 25 | return fmt.Sprintf("'%c'", r) 26 | } 27 | switch r { 28 | case 0x07: 29 | return "'\\a'" 30 | case 0x08: 31 | return "'\\b'" 32 | case 0x0C: 33 | return "'\\f'" 34 | case 0x0A: 35 | return "'\\n'" 36 | case 0x0D: 37 | return "'\\r'" 38 | case 0x09: 39 | return "'\\t'" 40 | case 0x0b: 41 | return "'\\v'" 42 | case 0x5c: 43 | return "'\\\\\\'" 44 | case 0x27: 45 | return "'\\''" 46 | case 0x22: 47 | return "'\\\"'" 48 | } 49 | if r < 0x10000 { 50 | return fmt.Sprintf("\\u%04x", r) 51 | } 52 | return fmt.Sprintf("\\U%08x", r) 53 | } 54 | -------------------------------------------------------------------------------- /hand/lexer/example_test.go: -------------------------------------------------------------------------------- 1 | package lexer_test 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/mewmew/uc/hand/lexer" 8 | ) 9 | 10 | func ExampleParseFile() { 11 | tokens, err := lexer.ParseFile("../../testdata/incorrect/lexer/long-char.c") 12 | if err != nil { 13 | log.Fatal(err) 14 | } 15 | for _, tok := range tokens { 16 | fmt.Printf("%-9v %q\n", tok.Kind.GoString(), tok.Val) 17 | } 18 | // Output: 19 | // Ident "int" 20 | // Ident "main" 21 | // Lparen "(" 22 | // Ident "void" 23 | // Rparen ")" 24 | // Lbrace "{" 25 | // Ident "char" 26 | // Ident "c" 27 | // Semicolon ";" 28 | // Ident "c" 29 | // Assign "=" 30 | // CharLit "'c'" 31 | // Semicolon ";" 32 | // Comment "// OK" 33 | // Ident "c" 34 | // Assign "=" 35 | // Error "unterminated character literal" 36 | // Ident "cc" 37 | // Error "unterminated character literal" 38 | // Semicolon ";" 39 | // Comment "// Not OK" 40 | // Rbrace "}" 41 | // EOF "" 42 | } 43 | 44 | func ExampleParseString() { 45 | tokens := lexer.ParseString("int main (void) { ; }") 46 | for i, tok := range tokens { 47 | fmt.Printf("token %d: %v\n", i, tok) 48 | } 49 | // Output: 50 | // token 0: token.Token{Kind: token.Ident, Val: "int", Pos: 0} 51 | // token 1: token.Token{Kind: token.Ident, Val: "main", Pos: 4} 52 | // token 2: token.Token{Kind: token.Lparen, Val: "(", Pos: 9} 53 | // token 3: token.Token{Kind: token.Ident, Val: "void", Pos: 10} 54 | // token 4: token.Token{Kind: token.Rparen, Val: ")", Pos: 14} 55 | // token 5: token.Token{Kind: token.Lbrace, Val: "{", Pos: 16} 56 | // token 6: token.Token{Kind: token.Semicolon, Val: ";", Pos: 18} 57 | // token 7: token.Token{Kind: token.Rbrace, Val: "}", Pos: 20} 58 | // token 8: token.Token{Kind: token.EOF, Val: "", Pos: 21} 59 | } 60 | -------------------------------------------------------------------------------- /hand/lexer/keywords.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | import ( 4 | "sort" 5 | 6 | "github.com/mewmew/uc/token" 7 | ) 8 | 9 | // keywords is the set of valid keywords in the µC programming language, sorted 10 | // alphabetically. 11 | var keywords []string 12 | 13 | func init() { 14 | keywords = make([]string, 0, len(token.Keywords)) 15 | for keyword := range token.Keywords { 16 | keywords = append(keywords, keyword) 17 | } 18 | sort.Strings(keywords) 19 | } 20 | -------------------------------------------------------------------------------- /irgen/emit.go: -------------------------------------------------------------------------------- 1 | package irgen 2 | -------------------------------------------------------------------------------- /noisy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for f in testdata/noisy/*/*.c; do 3 | echo "UC" 4 | ./compile.sh "${f}" 5 | echo -e "\n### UC output:" 6 | lli out.ll 7 | echo -e "\n\nClang" 8 | clang -o a.out "${f}" testdata/uc.ll 9 | 10 | echo -e "\n###Clang output:" 11 | ./a.out 12 | echo -e "\n" 13 | done 14 | -------------------------------------------------------------------------------- /presentation/01_lex/notes.md: -------------------------------------------------------------------------------- 1 | # Lexer 2 | 3 | ## Examples 4 | 5 | ### Correct 6 | 7 | * testdata/foo/bar.c 8 | 9 | ### Incorrect 10 | 11 | * testdata/foo/baz.c 12 | 13 | ## What is interesting with the design and implementation 14 | 15 | * Hand-written 16 | - State function, Rob Pike. 17 | - Encoding 18 | 19 | * Gocc generated 20 | - From BNF grammar 21 | 22 | * The Lexer Hack!! 23 | - Type keywords are identifiers 24 | 25 | ## What was difficult? 26 | 27 | * Line-comments ending with EOF 28 | - Hand-written lexer solved 29 | + EOF case initially not handled, now using two cases, one for new line one for EOF. 30 | - Gocc generated lexer solution: 31 | + Insert new-line at end of input. 32 | -------------------------------------------------------------------------------- /presentation/02_parse/notes.md: -------------------------------------------------------------------------------- 1 | # Parser 2 | 3 | ## Examples 4 | 5 | ### Correct 6 | 7 | * testdata/foo/bar.c 8 | 9 | ### Incorrect 10 | 11 | * testdata/foo/baz.c 12 | 13 | ## What is interesting with the design and implementation 14 | 15 | * Gocc generated 16 | - From BNF grammar 17 | 18 | * Wrapper around the hand-written lexer to unify the API of the two lexer implementations. 19 | + Since the Gocc generated parser is already expecting the Gocc lexer API. 20 | 21 | * For the cannonical LR-1 shift-reduce problem (dangling else) 22 | - Use the -a flag of Gocc so automatically resolve the conflict through maximal-munch. 23 | 24 | * Simplify and unify the grammar 25 | - Get rid of the Locals production rule, allow local variable definitions to occur anywhere in a function. 26 | 27 | * Construct the AST using production actions. << astx.NewFuncDecl(foo, bar) >> 28 | + Show BNF grammar, and demonstrate how gocc is able to generate a lexer and parser from it. 29 | 30 | * Associativity and precedence of binary operations 31 | - Directly from the Dragon book and the C spec. 32 | - Tree structure to define precedence. 33 | + Show example 34 | - Left or right side of production rule to define associativity. 35 | + Show example 36 | 37 | * User-friendly error messages 38 | - PR to Gocc. Basically print the next token and the expected followset when unable to shift or reduce. 39 | 40 | ## What was difficult? 41 | 42 | * Reduce-reduce conflicts introduced by The Lexer Hack. 43 | - Use a single production rule for type names and postpone type analysis to the semantic analysis stage. 44 | 45 | * Evaluate merging TopLevelDecl with Decl to simplify grammar 46 | - Turns out, this was probably not the right design choice, as it made the implementation of the irgen more difficult. We were no longer able to differentiate between local and global variables with ease. 47 | -------------------------------------------------------------------------------- /presentation/03_sem/notes.md: -------------------------------------------------------------------------------- 1 | # Semantic Analysis 2 | 3 | ## Examples 4 | 5 | ### Correct 6 | 7 | * testdata/foo/bar.c 8 | 9 | ### Incorrect 10 | 11 | * testdata/foo/baz.c 12 | 13 | ## What is interesting with the design and implementation 14 | 15 | * Design choice, forward declarations. Thus resolve identifiers in two passes. First file-scope declarations, then block scope-declarations. 16 | - Sem check: Step 1. Identifier resolution. Step 2: Type-checking. Step 3: Semantic analysis (always disallow nested functions, for now). 17 | 18 | * Tree walking 19 | 20 | ## What was difficult? 21 | 22 | * Tentative definitions. 23 | - Distinguish between declaration and definition. 24 | + Solution: Scope with `IsDef` method, which is different at file-scope and block-scope. 25 | -------------------------------------------------------------------------------- /presentation/04_05_irgen/notes.md: -------------------------------------------------------------------------------- 1 | # IR generation 2 | 3 | ## Examples 4 | 5 | ### Correct 6 | 7 | * testdata/foo/bar.c 8 | 9 | ### Incorrect 10 | 11 | * testdata/foo/baz.c 12 | 13 | ## What is interesting with the design and implementation 14 | 15 | ## What was difficult? 16 | -------------------------------------------------------------------------------- /presentation/testcases.patch: -------------------------------------------------------------------------------- 1 | Only in presentation/ts-120116/: 00README.txt 2 | Only in testdata/: encoding 3 | Only in testdata/: extra 4 | Only in presentation/ts-120116/incorrect/semantic: se35.o 5 | Only in testdata/: Makefile 6 | diff -w -r -u presentation/ts-120116/noisy/advanced/eval.c testdata/noisy/advanced/eval.c 7 | --- presentation/ts-120116/noisy/advanced/eval.c 2010-01-18 11:03:55.000000000 +0100 8 | +++ testdata/noisy/advanced/eval.c 2016-07-25 18:10:38.000000000 +0200 9 | @@ -112,6 +112,7 @@ 10 | return a; 11 | } 12 | } 13 | + return 0; 14 | } 15 | 16 | int main(void) { 17 | diff -w -r -u presentation/ts-120116/quiet/mips/m01.c testdata/quiet/mips/m01.c 18 | --- presentation/ts-120116/quiet/mips/m01.c 2010-01-18 11:03:55.000000000 +0100 19 | +++ testdata/quiet/mips/m01.c 2016-08-24 02:06:18.773319230 +0200 20 | @@ -10,6 +10,7 @@ 21 | 22 | int mov(int lb) { 23 | addi = lb; 24 | + return 0; 25 | } 26 | 27 | int main (void) { 28 | diff -w -r -u presentation/ts-120116/quiet/rtl/r06.c testdata/quiet/rtl/r06.c 29 | --- presentation/ts-120116/quiet/rtl/r06.c 2012-01-13 14:14:58.000000000 +0100 30 | +++ testdata/quiet/rtl/r06.c 2016-08-31 12:25:26.111448661 +0200 31 | @@ -14,5 +14,5 @@ 32 | } 33 | 34 | int main(void){ 35 | - fac(5); 36 | + return fac(5); 37 | } 38 | diff -w -r -u presentation/ts-120116/uc.c testdata/uc.c 39 | --- presentation/ts-120116/uc.c 2010-01-18 11:03:54.000000000 +0100 40 | +++ testdata/uc.c 2016-07-25 18:10:38.000000000 +0200 41 | @@ -16,6 +16,5 @@ 42 | 43 | 44 | int getstring(char s[]) { 45 | - scanf("%s",s); 46 | + return scanf("%s", s); 47 | } 48 | - 49 | Only in testdata/: uc.ll 50 | -------------------------------------------------------------------------------- /report/.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | -------------------------------------------------------------------------------- /report/1_intro.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | % Document 6 | 7 | \begin{document} 8 | 9 | \tableofcontents 10 | 11 | \include{sections/1_introduction} 12 | 13 | %\bibliography{references} 14 | 15 | \end{document} 16 | -------------------------------------------------------------------------------- /report/2_lex.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | \title{µC Compiler Design - Assignment 1\\Lexical Analysis} 6 | \author{Alexander Andersson \and Robin Eklind} 7 | \date{\today} 8 | 9 | % Document 10 | 11 | \begin{document} 12 | 13 | % === [ Front matter ] ========================================================= 14 | 15 | \pagenumbering{roman} 16 | 17 | % --- [ Title page ] ----------------------------------------------------------- 18 | 19 | \maketitle 20 | 21 | \clearpage 22 | 23 | \tableofcontents 24 | 25 | \clearpage 26 | 27 | % === [ Main matter ] ========================================================== 28 | 29 | \pagenumbering{arabic} 30 | 31 | \include{sections/2_lexical_analysis} 32 | 33 | \bibliography{references} 34 | 35 | % === [ Appendices ] =========================================================== 36 | 37 | \clearpage 38 | 39 | \appendix 40 | \setcounter{secnumdepth}{0} 41 | \section{Appendices} 42 | \setcounter{secnumdepth}{3} 43 | \renewcommand{\thesubsection}{\Alph{subsection}} 44 | 45 | \input{sections/appendices/2_lexical_analysis} 46 | 47 | \end{document} 48 | -------------------------------------------------------------------------------- /report/3_parse.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | \title{µC Compiler Design - Assignment 2\\Syntactic Analysis} 6 | \author{Alexander Andersson \and Robin Eklind} 7 | \date{\today} 8 | 9 | % Document 10 | 11 | \begin{document} 12 | 13 | % === [ Front matter ] ========================================================= 14 | 15 | \pagenumbering{roman} 16 | 17 | % --- [ Title page ] ----------------------------------------------------------- 18 | 19 | \maketitle 20 | 21 | \clearpage 22 | 23 | \tableofcontents 24 | 25 | \clearpage 26 | 27 | % === [ Main matter ] ========================================================== 28 | 29 | \pagenumbering{arabic} 30 | 31 | \include{sections/3_syntactic_analysis} 32 | 33 | \bibliography{references} 34 | 35 | % === [ Appendices ] =========================================================== 36 | 37 | \clearpage 38 | 39 | \appendix 40 | \setcounter{secnumdepth}{0} 41 | \section{Appendices} 42 | \setcounter{secnumdepth}{3} 43 | \renewcommand{\thesubsection}{\Alph{subsection}} 44 | 45 | \include{sections/appendices/3_syntactic_analysis} 46 | 47 | \end{document} 48 | -------------------------------------------------------------------------------- /report/4_sem.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | \title{µC Compiler Design - Assignment 3\\Semantic Analysis} 6 | \author{Alexander Andersson \and Robin Eklind} 7 | \date{\today} 8 | 9 | % Document 10 | 11 | \begin{document} 12 | 13 | % === [ Front matter ] ========================================================= 14 | 15 | \pagenumbering{roman} 16 | 17 | % --- [ Title page ] ----------------------------------------------------------- 18 | 19 | \maketitle 20 | 21 | \clearpage 22 | 23 | \tableofcontents 24 | 25 | \clearpage 26 | 27 | % === [ Main matter ] ========================================================== 28 | 29 | \pagenumbering{arabic} 30 | 31 | \include{sections/4_semantic_analysis} 32 | 33 | \bibliography{references} 34 | 35 | % === [ Appendices ] =========================================================== 36 | 37 | \clearpage 38 | 39 | \appendix 40 | \setcounter{secnumdepth}{0} 41 | \section{Appendices} 42 | \setcounter{secnumdepth}{3} 43 | \renewcommand{\thesubsection}{\Alph{subsection}} 44 | 45 | \include{sections/appendices/4_semantic_analysis} 46 | 47 | \end{document} 48 | -------------------------------------------------------------------------------- /report/5_ir.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | \title{µC Compiler Design - Assignment 4\\Intermediate Representation} 6 | \author{Alexander Andersson \and Robin Eklind} 7 | \date{\today} 8 | 9 | % Document 10 | 11 | \begin{document} 12 | 13 | % === [ Front matter ] ========================================================= 14 | 15 | \pagenumbering{roman} 16 | 17 | % --- [ Title page ] ----------------------------------------------------------- 18 | 19 | \maketitle 20 | 21 | \clearpage 22 | 23 | \tableofcontents 24 | 25 | \clearpage 26 | 27 | % === [ Main matter ] ========================================================== 28 | 29 | \pagenumbering{arabic} 30 | 31 | \include{sections/5_intermediate_representation} 32 | 33 | \bibliography{references} 34 | 35 | % === [ Appendices ] =========================================================== 36 | 37 | \clearpage 38 | 39 | \appendix 40 | \setcounter{secnumdepth}{0} 41 | \section{Appendices} 42 | \setcounter{secnumdepth}{3} 43 | \renewcommand{\thesubsection}{\Alph{subsection}} 44 | 45 | \include{sections/appendices/5_intermediate_representation} 46 | 47 | \end{document} 48 | -------------------------------------------------------------------------------- /report/6_ir_gen.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | % Document 6 | 7 | \begin{document} 8 | 9 | \tableofcontents 10 | 11 | \include{sections/6_ir_generation} 12 | 13 | %\bibliography{references} 14 | 15 | \end{document} 16 | -------------------------------------------------------------------------------- /report/7_con.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | % Document 6 | 7 | \begin{document} 8 | 9 | \tableofcontents 10 | 11 | \include{sections/7_conclusion} 12 | 13 | %\bibliography{references} 14 | 15 | \end{document} 16 | -------------------------------------------------------------------------------- /report/Makefile: -------------------------------------------------------------------------------- 1 | all: uc.pdf clean_aux 2 | 3 | uc.pdf: inc 4 | pdflatex uc.tex 5 | bibtex uc 6 | pdflatex uc.tex 7 | pdflatex uc.tex 8 | 9 | # *.tex -> *.pdf 10 | TEX = $(wildcard *.tex) 11 | PDF = $(TEX:.tex=.pdf) 12 | 13 | .PHONY: clean inc inc/uparse inc/ulex inc/usem 14 | inc inc/uparse inc/ulex inc/usem: 15 | make -C $@/ 16 | 17 | clean_aux: 18 | rm -f *.log *.out *.toc *.bbl *.blg *.dvi *.rtf *.bcf *-blx.bib *.run.xml 19 | find . -iname "*.aux" -type f -delete 20 | 21 | clean: clean_aux 22 | rm -f uc.pdf 1_intro.pdf 2_lex.pdf 3_parse.pdf 4_sem.pdf 5_ir.pdf 6_ir_gen.pdf 7_con.pdf app.pdf 23 | make -C inc/ clean 24 | 25 | # TODO: Remove temporary sections from Makefile when the report is finalized. 26 | 27 | lex: 2_lex.pdf clean_aux 28 | parse: 3_parse.pdf clean_aux 29 | sem: 4_sem.pdf clean_aux 30 | ir: 5_ir.pdf clean_aux 31 | 32 | %.pdf: %.tex 33 | pdflatex $< 34 | bibtex $* 35 | pdflatex $< 36 | pdflatex $< 37 | 38 | 2_lex.pdf: inc/ulex 39 | 40 | 3_parse.pdf: inc/uparse 41 | 42 | 4_sem.pdf: inc/usem 43 | 44 | tmpsec: 1_intro.pdf 2_lex.pdf 3_parse.pdf 4_sem.pdf 5_ir.pdf 6_ir_gen.pdf 7_con.pdf app.pdf 45 | -------------------------------------------------------------------------------- /report/app.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | 3 | \usepackage{preamble} 4 | 5 | % Document 6 | 7 | \begin{document} 8 | 9 | \tableofcontents 10 | 11 | \include{sections/appendices} 12 | 13 | %\bibliography{references} 14 | 15 | \end{document} 16 | -------------------------------------------------------------------------------- /report/inc/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: ulex uparse usem 3 | 4 | ulex uparse usem: 5 | make -C $@/ 6 | 7 | clean: 8 | make -C uparse clean 9 | make -C ulex clean 10 | make -C usem clean 11 | 12 | .PHONY: all ulex uparse usem clean 13 | -------------------------------------------------------------------------------- /report/inc/sections/3_syntactic_analysis/ast_doc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/report/inc/sections/3_syntactic_analysis/ast_doc.pdf -------------------------------------------------------------------------------- /report/inc/sections/4_semantic_analysis/types_doc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mewmew/uc/5b0a9c42b013c0f2f0c922f0ea454dabe1ea05bf/report/inc/sections/4_semantic_analysis/types_doc.pdf -------------------------------------------------------------------------------- /report/inc/sections/6_ir_generation/r06.c: -------------------------------------------------------------------------------- 1 | //#include 2 | 3 | int fac(int n) { 4 | int i; 5 | int p; 6 | if (n<0) return 0; 7 | i = 0; 8 | p = 1; 9 | while (i:0 3 | %1 = alloca i32 4 | store i32 %n, i32* %1 5 | %i = alloca i32 6 | %p = alloca i32 7 | %2 = load i32, i32* %1 8 | %3 = icmp slt i32 %2, 0 9 | br i1 %3, label %4, label %5 10 | ;