compiler.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Author: simon
  2. // Author: ynwdlxm@163.com
  3. // Date: 2022/10/19 14:39
  4. // Desc: Compiler
  5. package compiler
  6. import (
  7. "github/runnignwater/monkey/ast"
  8. "github/runnignwater/monkey/code"
  9. "github/runnignwater/monkey/object"
  10. )
  11. type Compiler struct {
  12. instructions code.Instructions // hold the generated bytecode
  13. constants []object.Object // slice that serves as our constant pool
  14. }
  15. func New() *Compiler {
  16. return &Compiler{
  17. instructions: code.Instructions{},
  18. constants: []object.Object{},
  19. }
  20. }
  21. func (c *Compiler) Compile(node ast.Node) error {
  22. switch node := node.(type) {
  23. case *ast.Program:
  24. for _, s := range node.Statements {
  25. err := c.Compile(s)
  26. if err != nil {
  27. return err
  28. }
  29. }
  30. case *ast.ExpressionStatement:
  31. err := c.Compile(node.Expression)
  32. if err != nil {
  33. return err
  34. }
  35. case *ast.InfixExpression:
  36. err := c.Compile(node.Left)
  37. if err != nil {
  38. return err
  39. }
  40. err = c.Compile(node.Right)
  41. if err != nil {
  42. return err
  43. }
  44. case *ast.IntegerLiteral:
  45. integer := &object.Integer{Value: node.Value}
  46. c.emit(code.OpConstant, c.addConstant(integer))
  47. }
  48. return nil
  49. }
  50. func (c *Compiler) addConstant(obj object.Object) int {
  51. c.constants = append(c.constants, obj)
  52. return len(c.constants) - 1
  53. }
  54. func (c *Compiler) addInstruction(ins []byte) int {
  55. posNewInstruction := len(c.instructions)
  56. c.instructions = append(c.instructions, ins...)
  57. return posNewInstruction
  58. }
  59. // emit generate an instruction and add it to the results,
  60. // either by printing it, writing it to a file or
  61. // by adding it to a collection in memory
  62. //
  63. // op code.Opcode
  64. //
  65. // operands [operand]int
  66. func (c *Compiler) emit(op code.Opcode, operands ...int) int {
  67. ins := code.Make(op, operands...)
  68. pos := c.addInstruction(ins)
  69. return pos
  70. }
  71. func (c *Compiler) ByteCode() *ByteCode {
  72. return &ByteCode{
  73. Instructions: c.instructions,
  74. Constants: c.constants,
  75. }
  76. }
  77. type ByteCode struct {
  78. Instructions code.Instructions
  79. Constants []object.Object
  80. }