A "high-level" language for the Gameboy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.4 KiB

  1. import { parse } from "./parser"
  2. import { convertIR } from "./ir"
  3. import type { Attr, Decl, Stmt, Type, VarDecl } from "./ast"
  4. type SymbolDefn = {
  5. attrs: Array<Attr>,
  6. name: string,
  7. type: Type
  8. }
  9. type SymbolMap = {
  10. [name: string]: SymbolDefn
  11. }
  12. // TODO: Support more than one TU
  13. export const compile = (source: string): string => {
  14. // 1. Parse
  15. const ast = parse(source)
  16. // 2. Partition declarations and statements
  17. const decls = ast.filter((x): x is Decl => x.type == "decl")
  18. const stmts = ast.filter((x): x is Stmt => x.type == "stmt")
  19. console.log("Declarations", decls)
  20. console.log("Statements", stmts)
  21. // 3. Create top-level symbol map
  22. const symbols = processDecls(decls)
  23. console.log("Symbols", symbols)
  24. // TODO: Some form of type-checking
  25. // 4. Generate IR
  26. const ir = convertIR(stmts)
  27. console.log("IR", ir)
  28. return ""
  29. }
  30. export const processDecls = (decls: Array<Decl>): SymbolMap => decls.reduce((symbols, decl) => {
  31. const symbol = processVarDecl(symbols, decl)
  32. return {
  33. ...symbols,
  34. [symbol.name]: symbol,
  35. }
  36. }, {})
  37. export const processVarDecl = (symbols: SymbolMap, decl: VarDecl): SymbolDefn => {
  38. if (typeof symbols[decl.name] !== 'undefined') {
  39. throw new Error(`a variable named \`${decl.name}' is already defined`)
  40. }
  41. return {
  42. attrs: decl.attrs,
  43. name: decl.name,
  44. type: decl.args.type,
  45. }
  46. }