476 words
2 minutes
260108_c_rust_crusted_interpreter
2026-01-08

link#


자료출처: Ahthor|🔝|#

우선 C로 작성|🔝|#

#include <stdio.h>
#include <stdlib.h>

typedef double Value;

/* -------- OpCode -------- */

typedef enum { OP_RETURN, OP_CONSTANT } OpCode;

/* Instruction with operand */
typedef struct {
    OpCode opcode;
    size_t operand; /* used only for OP_CONSTANT */
} Instruction;

/* -------- Chunk -------- */

typedef struct {
    Instruction *code;
    size_t code_count;
    size_t code_capacity;

    Value *constants;
    size_t constants_count;
    size_t constants_capacity;

    size_t *lines;
} Chunk;

/* -------- Utilities -------- */

static void *grow_array(void *array, size_t old_count, size_t new_count,
                        size_t elem_size) {
    (void)old_count;
    return realloc(array, elem_size * new_count);
}

/* -------- Chunk API -------- */

void init_chunk(Chunk *chunk) {
    chunk->code = NULL;
    chunk->code_count = 0;
    chunk->code_capacity = 0;

    chunk->constants = NULL;
    chunk->constants_count = 0;
    chunk->constants_capacity = 0;

    chunk->lines = NULL;
}

void free_chunk(Chunk *chunk) {
    free(chunk->code);
    free(chunk->constants);
    free(chunk->lines);
    init_chunk(chunk);
}

size_t add_constant(Chunk *chunk, Value value) {
    if (chunk->constants_count + 1 > chunk->constants_capacity) {
        size_t old = chunk->constants_capacity;
        chunk->constants_capacity = old < 8 ? 8 : old * 2;
        chunk->constants = grow_array(chunk->constants, old,
                                      chunk->constants_capacity, sizeof(Value));
    }

    chunk->constants[chunk->constants_count] = value;
    return chunk->constants_count++;
}

void write_chunk(Chunk *chunk, OpCode opcode, size_t operand, size_t line) {
    if (chunk->code_count + 1 > chunk->code_capacity) {
        size_t old = chunk->code_capacity;
        chunk->code_capacity = old < 8 ? 8 : old * 2;

        chunk->code = grow_array(chunk->code, old, chunk->code_capacity,
                                 sizeof(Instruction));

        chunk->lines =
            grow_array(chunk->lines, old, chunk->code_capacity, sizeof(size_t));
    }

    chunk->code[chunk->code_count] = (Instruction){opcode, operand};
    chunk->lines[chunk->code_count] = line;
    chunk->code_count++;
}

void disassemble_chunk(Chunk *chunk, const char *name) {
    printf("== %s ==\n", name);
    for (size_t i = 0; i < chunk->code_count; i++) {
        printf("%04zu ", i);
        switch (chunk->code[i].opcode) {
        case OP_RETURN:
            printf("OP_RETURN\n");
            break;
        case OP_CONSTANT:
            printf("%-16s %4zu ", "OP_CONSTANT", chunk->code[i].operand);
            printf("%g\n", chunk->constants[chunk->code[i].operand]);
            break;
        default:
            printf("Unknown opcode\n");
            break;
        }
    }
}

/* -------- Main -------- */

int main(void) {
    Chunk chunk;
    init_chunk(&chunk);

    size_t constant = add_constant(&chunk, 1.2);
    write_chunk(&chunk, OP_CONSTANT, constant, 123);

    write_chunk(&chunk, OP_RETURN, 0, 123);

    disassemble_chunk(&chunk, "test chunk");

    free_chunk(&chunk);
    return 0;
}

러스트로 코드를 변환해 보자.|🔝|#

#![allow(non_camel_case_types)]

pub type Value = f64;

#[derive(Debug)]
pub enum OpCode {
    OP_RETURN,
    OP_CONSTANT(usize),
}

#[derive(Debug)]
pub struct Chunk {
    code: Vec<OpCode>,
    constants: Vec<Value>,
    lines: Vec<usize>,
}

impl Chunk {
    pub fn new() -> Chunk {
        Chunk {
            code: Vec::new(),
            constants: Vec::new(),
            lines: Vec::new(),
        }
    }

    pub fn add_constant(&mut self, value: Value) -> usize {
        self.constants.push(value);
        self.constants.len() - 1
    }

    pub fn write(&mut self, op: OpCode, line: usize) {
        self.code.push(op);
        self.lines.push(line);
    }

    pub fn disassemble(&self, name: &str) {
        println!("== {name} ==");
        for (n, inst) in self.code.iter().enumerate() {
            println!("{n:04}, {inst:?}");
        }
    }
}


fn main() {
    println!("Hello, lox!");

    let mut chunk = Chunk::new();
    let constant = chunk.add_constant(1.2);
    chunk.write(OP_CONSTANT(constant), 1);
    chunk.write(OP_RETURN, 1);
    chunk.disassemble("test chunk");
}
260108_c_rust_crusted_interpreter
https://younghakim7.github.io/blog/posts/260108_c_rust_crusted_interpreter/
Author
YoungHa
Published at
2026-01-08