class_name CPU
extends Node

signal cpu_tick

var cobor_vm := CoborVirtualMachine.new()
var running := false
var register_size := 8
var modules : Array[Module]

func _ready() -> void:
	cobor_vm.set_registers(register_size,[])
	var register_index := 1 
	for child in get_children():
		if child is Module:
			var module := child as Module
			modules.push_back(module)
			register_size += module.set_registers(register_index)

func run_step() -> void:
	if not running:
		cobor_vm.set_registers(register_size,[])
		running = true
	_tick()

func run() -> void:
	if not running:
		cobor_vm.set_registers(register_size,[])
		running = true
	$CPUClock.start()

func _tick()->void:
	for module in modules: 
		module.early_tick()
	var err := cobor_vm.run_step()
	if not err.is_empty():
		print(err)
	if cobor_vm.get_program_counter() >= cobor_vm.get_program_size():
		stop()
	for module in modules: 
		module.late_tick()
	emit_signal("cpu_tick")

func pause()->void:
	$CPUClock.stop()

func stop()->void:
	running = false
	$CPUClock.stop()

func compile_code(source_code: String)->void:
	var errors := cobor_vm.parse_source_code(source_code)
	if errors.is_empty():
		print("Compiling Ok!")
	else:
		for error in errors:
			print(error)
