vety-language/vm/main.c

154 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "vm.h"
#include "native.h"
#include "file.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main() {
system("chcp 65001");
char* filepath = "../main.vt";
// 创建虚拟机实例
VM* vm = vm_create();
if (!vm) {
fprintf(stderr, "Failed to create VM\n");
return 1;
}
// 注册原生函数
vm_register_native_function(vm, "print", native_print_const);
// 定义一个使用嵌套if语句的程序
uint8_t code[] = {
// 外层if: 比较R0和R1
OP_LOAD_CONST, R0, 0, // R0 = 10
OP_LOAD_CONST, R1, 1, // R1 = 20
OP_CMP_NE, R2, R0, R1, // R2 = R0 != R1
OP_JMP_IF_FALSE, R2, 0, 50, // 如果R2为假跳转到外层else分支
// 外层if的then分支
OP_MOV_IMM, R3, 2,
OP_NATIVE_CALL, 0, 1, R3,
// 内层if: 比较R0是否小于R1
OP_CMP_LT, R4, R0, R1,
OP_JMP_IF_FALSE, R4, 0, 39,
OP_MOV_IMM, R3, 4,
OP_NATIVE_CALL, 0, 1, R3,
OP_JMP, 0, 45, // 跳过内层else分支
// 内层else分支
OP_MOV_IMM, R3, 5,
OP_NATIVE_CALL, 0, 1, R3,
OP_END_IF, // 内层if结束
OP_JMP, 0, 58, // 跳过外层else分支
// 外层else分支
OP_MOV_IMM, R3, 3,
OP_NATIVE_CALL, 0, 1, R3,
OP_END_IF, // 外层if结束
OP_HALT // 程序结束
};
Program program = {
.code_size = sizeof(code),
.constants.entries = (Constant[]){
{.type = TYPE_INT64, .value = {.int64_val = 10}}, // 常量0: 10
{.type = TYPE_INT64, .value = {.int64_val = 20}}, // 常量1: 20
{.type = TYPE_STRING, .value = {.string_val = {.value = "Numbers are equal\n", .len = 18}}},
{.type = TYPE_STRING, .value = {.string_val = {.value = "Numbers are not equal\n", .len = 22}}},
{.type = TYPE_STRING, .value = {.string_val = {.value = "First number is smaller\n", .len = 22}}}
},
.constants.count = 5,
.constants.capacity = 10
};
// 加载程序到虚拟机
program.code = code;
vm_load(vm, &program);
// 执行程序
vm_eval(vm);
if (0) return 0; //是否打印
// 打印字节码
print_bytecode(program);
// 在vm_eval调用之前添加以下代码
printf("-------------------------------------------\n\n");
// 检查执行是否出错
if (vm->error != VM_SUCCESS) {
fprintf(stderr, "执行错误: %s\n", vm_get_error_message(vm));
fprintf(stderr, "指令位置: %lu\n", vm->error_ip);
fprintf(stderr, "操作码: 0x%02X\n", vm->error_opcode);
vm_destroy(vm);
return 1;
}
printf("-------------------------------------------\n");
// 打印常量池
printf("常量池:\n");
printf("索引 | 类型 | 值\n");
printf("-------------------------------------------\n");
for (int i = 0; i < program.constants.count; i++) {
Constant constant = program.constants.entries[i];
switch (constant.type) {
case TYPE_INT64:
printf("%d | i64 | %lld \n", i, constant.value.int64_val);
break;
case TYPE_STRING:
printf("%d | string | \"%s\" \n", i, constant.value.string_val.value);
break;
default:
break;
}
}
printf("-------------------------------------------\n\n");
// 栈
printf("栈:\n");
printf("索引 | 值\n");
printf("-------------------------------------------\n");
for (int i = 0; i < vm->sp; i++) {
printf("%d | %llu \n", i, vm->stack[i]);
}
if (vm->sp == 0) printf("空栈\n");
printf("-------------------------------------------\n\n");
// 打印寄存器
printf("寄存器:\n");
printf("索引 | 值\n");
printf("-------------------------------------------\n");
for (int i = 0; i < 5; i++) {
printf("%d | %llu \n", i, vm->registers[i]);
}
printf("-------------------------------------------\n\n");
// 打印函数表
printf("函数表:\n");
printf("索引 | 地址 | 局部变量个数 | 参数个数 \n");
printf("------------------------------------------------------------------\n");
for (int i = 0; i < vm->function_count; i++) {
Function function = vm->functions[i];
printf("%d(%s) | %llu | %d | %d \n", i, function.name, function.code_offset, function.local_count, function.param_count);
}
// 打印原生函数表
printf("-------------------------------------------\n\n");
printf("原生函数表:\n");
printf("索引 | 函数名\n");
printf("-------------------------------------------\n");
for (int i = 0; i < vm->native_function_count; i++) {
printf("%d | %s \n", i, vm->native_functions[i].name);
}
printf("-------------------------------------------\n\n");
vm_destroy(vm);
return 0;
}