| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- // Author: simon
- // Author: ynwdlxm@163.com
- // Date: 2022/10/19 14:39
- // Desc: Compiler
- package compiler
- import (
- "github/runnignwater/monkey/ast"
- "github/runnignwater/monkey/code"
- "github/runnignwater/monkey/object"
- )
- type Compiler struct {
- instructions code.Instructions // hold the generated bytecode
- constants []object.Object // slice that serves as our constant pool
- }
- func New() *Compiler {
- return &Compiler{
- instructions: code.Instructions{},
- constants: []object.Object{},
- }
- }
- func (c *Compiler) Compile(node ast.Node) error {
- switch node := node.(type) {
- case *ast.Program:
- for _, s := range node.Statements {
- err := c.Compile(s)
- if err != nil {
- return err
- }
- }
- case *ast.ExpressionStatement:
- err := c.Compile(node.Expression)
- if err != nil {
- return err
- }
- case *ast.InfixExpression:
- err := c.Compile(node.Left)
- if err != nil {
- return err
- }
- err = c.Compile(node.Right)
- if err != nil {
- return err
- }
- case *ast.IntegerLiteral:
- integer := &object.Integer{Value: node.Value}
- c.emit(code.OpConstant, c.addConstant(integer))
- }
- return nil
- }
- func (c *Compiler) addConstant(obj object.Object) int {
- c.constants = append(c.constants, obj)
- return len(c.constants) - 1
- }
- func (c *Compiler) addInstruction(ins []byte) int {
- posNewInstruction := len(c.instructions)
- c.instructions = append(c.instructions, ins...)
- return posNewInstruction
- }
- // emit generate an instruction and add it to the results,
- // either by printing it, writing it to a file or
- // by adding it to a collection in memory
- //
- // op code.Opcode
- //
- // operands [operand]int
- func (c *Compiler) emit(op code.Opcode, operands ...int) int {
- ins := code.Make(op, operands...)
- pos := c.addInstruction(ins)
- return pos
- }
- func (c *Compiler) ByteCode() *ByteCode {
- return &ByteCode{
- Instructions: c.instructions,
- Constants: c.constants,
- }
- }
- type ByteCode struct {
- Instructions code.Instructions
- Constants []object.Object
- }
|