package core

import (
	"git.akyoto.dev/cli/q/src/asm"
	"git.akyoto.dev/cli/q/src/ast"
	"git.akyoto.dev/cli/q/src/errors"
	"git.akyoto.dev/cli/q/src/expression"
)

// CompileDefinition compiles a variable definition.
func (f *Function) CompileDefinition(node *ast.Define) error {
	left := node.Expression.Children[0]
	right := node.Expression.Children[1]

	if left.IsLeaf() {
		variable, err := f.Define(left)

		if err != nil {
			return err
		}

		typ, err := f.ExpressionToRegister(right, variable.Register)

		if err != nil {
			return err
		}

		variable.Type = typ

		if variable.Type == nil {
			return errors.New(errors.CouldNotInferType, f.File, node.Expression.Token.End())
		}

		f.AddVariable(variable)
		return nil
	}

	if !ast.IsFunctionCall(right) {
		return errors.New(errors.NotImplemented, f.File, node.Expression.Token.Position)
	}

	count := 0
	called, err := f.CompileCall(right)

	if err != nil {
		return err
	}

	return left.EachLeaf(func(leaf *expression.Expression) error {
		variable, err := f.Define(leaf)

		if err != nil {
			return err
		}

		if called != nil {
			variable.Type = called.Output[count].Type
		}

		f.RegisterRegister(asm.MOVE, variable.Register, f.CPU.Output[count])
		f.AddVariable(variable)
		count++
		return nil
	})
}