{"id":13714351,"url":"https://github.com/fzipp/oberon-compiler","last_synced_at":"2025-04-13T23:24:10.035Z","repository":{"id":57629526,"uuid":"406850707","full_name":"fzipp/oberon-compiler","owner":"fzipp","description":"N. Wirth's Project Oberon RISC compiler ported to Go.","archived":false,"fork":false,"pushed_at":"2024-02-12T21:10:49.000Z","size":35,"stargazers_count":16,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-27T13:40:48.235Z","etag":null,"topics":["compiler","go","golang","oberon","oberon-07","oberon-compiler","project-oberon","wirth","wirth-oberon"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fzipp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-15T16:43:03.000Z","updated_at":"2025-02-14T09:47:27.000Z","dependencies_parsed_at":"2024-06-20T14:47:00.603Z","dependency_job_id":"b56acc5d-f850-4747-a650-60ae8c2ebbe3","html_url":"https://github.com/fzipp/oberon-compiler","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fzipp%2Foberon-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fzipp%2Foberon-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fzipp%2Foberon-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fzipp%2Foberon-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fzipp","download_url":"https://codeload.github.com/fzipp/oberon-compiler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248795189,"owners_count":21162726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","go","golang","oberon","oberon-07","oberon-compiler","project-oberon","wirth","wirth-oberon"],"created_at":"2024-08-02T23:01:57.631Z","updated_at":"2025-04-13T23:24:09.998Z","avatar_url":"https://github.com/fzipp.png","language":"Go","funding_links":[],"categories":["Repositories"],"sub_categories":[],"readme":"# oberon-compiler\n\nThis is a port of the\n[Project Oberon](https://people.inf.ethz.ch/wirth/ProjectOberon/index.html)\ncompiler for RISC-5 (not to be confused with RISC-V) from Oberon to Go.\nThe compiled binaries can be run  in a Project Oberon RISC emulator like\nPeter de Wachter's [oberon-risc-emu](https://github.com/pdewacht/oberon-risc-emu)\nor on my [port of it to Go](https://github.com/fzipp/oberon) —\nor on real Project Oberon FPGA hardware, of course.\n\nThe source code of the original compiler by Niklaus Wirth can be found on\nthe website linked above.\n\n## Installation\n\n```\n$ go install github.com/fzipp/oberon-compiler/cmd/oc@latest\n```\n\n## Usage\n```\noc [-s] modfile...\n\nFlags:\n    -s  Overwrites existing symbol file on changes.\n```\n\n### Example 1: Compiling the Oberon core modules\n\nDownload the source code of the Project Oberon core modules from\n[Wirth's homepage](https://people.inf.ethz.ch/wirth/ProjectOberon/index.html)\n(the *.Mod files  in the  first row).\n\nCompile the inner core modules:\n\n```\n$ oc Kernel.Mod FileDir.Mod Files.Mod Modules.Mod\n```\n\nCompile the outer core modules:\n\n```\n$ oc Input.Mod Display.Mod Viewers.Mod Fonts.Mod Texts.Mod Oberon.Mod MenuViewers.Mod TextFrames.Mod System.Mod Edit.Mod\n```\n\nThe compilation result is a RISC object file (.rsc) and a symbol file (.smb)\nfor each module.\n\n### Example 2: Hello World\n\nThis requires the compiled core modules from the previous example, specifically\nthe symbol files `Texts.smb` and `Oberon.smb`, because the example code will\nimport these two modules.\n\nCreate a source file named `Hello.Mod` containing the following code:\n\n```\nMODULE Hello;\n\nIMPORT Texts, Oberon;\n\nVAR W: Texts.Writer;\n\nPROCEDURE World*;\nBEGIN\n  Texts.WriteString(W, \"hello, world\");\n  Texts.WriteLn(W);\n  Texts.Append(Oberon.Log, W.buf);\nEND World;\n\nBEGIN\n  Texts.OpenWriter(W);\nEND Hello.\n```\n\nCompile it with the Oberon compiler `oc`:\n\n```\n$ oc Hello.Mod\nOR Compiler  8.3.2020; ported to Go\n  compiling Hello new symbol file 33 40 E4DFD669\n```\n\nThis results in two new files:\n\n```\nHello.rsc Hello.smb\n```\n\nOne is the RISC object file (.rsc), and the other is the symbol file (.smb).\n\n## Motivation\n\nMy motivation was the same as\n\u003ca href=\"https://github.com/arnobastenhof\"\u003e@arnobastenhof\u003c/a\u003e's motivation to\n[port a subset](https://github.com/arnobastenhof/oberon) of Wirth's\nreference implementation for the Oberon-07 language to C:\n\n\u003e \"It was written primarily for self-educational purposes as a kind of\n\u003e intensive code reading exercise.\"\n\nHaving a compiler available outside the target system also turned out to be\nuseful in practice. One can develop code in a familiar environment before\ntransferring it to the target system.\n\n## Porting Notes\n\n- I resisted the temptation to remove limits like the maximum\n  length of strings or identifiers in order to keep source code \n  written for this compiler compatible with the original compiler.\n  These restrictions can also have an educational value as Hanspeter\n  Mössenböck points out in\n  [Compiler Construction - The Art of Niklaus Wirth](ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe00b.pdf).\n- `REPEAT...UNTIL x;` was translated to Go as `for {...; if x { break } }`.\n  I did not rewrite these loops as loops with the condition at the start\n  (which would be idiomatic Go) in order to preserve the original\n  control flow.\n- I kept the \"single return\" style of Oberon and did not translate it to the\n  \"early return\" style that is idiomatic in Go.\n- I kept the short names, but I changed the capitalization of many variables\n  and struct fields consistently to \"camel case\". I had to slightly adjust the\n  names of some functions and variables that would otherwise clash with Go\n  keywords, specifically `import` and `type`.\n- I introduced the types `ors.Sym`, `orb.Form` and `orb.Class`, and prefixed\n  the names of their enumeration-like constants, as it is customary in Go.\n  The original code uses raw integer types for them, but I found the additional \n  type safety helpful.\n- The functionality is implemented in Go as methods on types (`ors.Scanner`,\n  `orp.Parser`, `orb.Base`, `org.Generator`), not as free functions in\n  \"flat\" packages with package scoped variables. This is a deviation from the\n  original implementation, but it allows the creation of multiple compiler\n  instances, for example to compile multiple modules in parallel with\n  goroutines.\n- I used a map for `ors.keyTab` instead of an array-based lookup table, and a\n  slice for `orp.Parser.pbsList` instead of a linked list.\n- I extracted two instances of duplicated code fragments in the scanner\n  as two new methods: `ors.Scanner.hexDigit` and `ors.Scanner.decimalInteger`.\n- Non-compilation errors like I/O errors are propagated as panics,\n  with `orp.Compile` acting as the boundary where they are recovered\n  and transformed back into a regular error return value.\n- `DIV` and `MOD` in Oberon are defined differently than `/` and `%` in Go\n  (floored division vs. truncated division). In Oberon `(-15) DIV 4 = -4` and\n  `(-15) MOD 4 = 1`, whereas in Go `(-15) / 4 == -3` and `(-15) % 4 == -3`.\n  The original code frequently uses `DIV` and `MOD` for bit shifting and\n  masking. The translated code uses bitwise operators such as `\u003c\u003c`, `\u003e\u003e`\n  and `\u0026` instead where appropriate.\n\n## License\n\nThis project is free and open source software licensed under the\n[Project Oberon License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffzipp%2Foberon-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffzipp%2Foberon-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffzipp%2Foberon-compiler/lists"}