text: /* ************************************************************************** */
  /*                                                                            */
  /*                                                        :::      ::::::::   */
  /*   data_processing_arguments.c                        :+:      :+:    :+:   */
  /*                                                    +:+ +:+         +:+     */
  /*   By: msaliuta <msaliuta@student.42.fr>          +#+  +:+       +#+        */
  /*                                                +#+#+#+#+#+   +#+           */
  /*   Created: 2019/09/06 17:48:57 by mzhurba           #+#    #+#             */
  /*   Updated: 2019/09/15 17:58:33 by msaliuta         ###   ########.fr       */
  /*                                                                            */
  /* ************************************************************************** */
  
  #include "asm.h"
  
  int8_t	read_and_code_args(t_pars *pars, t_entity **curr, t_inst *inst)
  {
  	int8_t	code;
  	int8_t	class;
  	int		arg_num;
  
  	arg_num = 0;
  	code = 0;
  	while (arg_num < inst->args_num)
  	{
  		if ((*curr)->class == REGISTER || (*curr)->class == DIRECT
  			|| (*curr)->class == DIRECT_LABEL || (*curr)->class == INDIRECT
  			|| (*curr)->class == INDIRECT_LABEL)
  		{
  			class = get_one_arg(pars, curr, inst, arg_num);
  			code |= get_type_code(class) << (2 * (3 - arg_num));
  			*curr = (*curr)->next;
  		}
  		else
  			terminate_syntax(pars, *curr, false);
  		if (arg_num++ < inst->args_num - 1)
  			(*curr)->class == SEPARATOR ?
  			*curr = (*curr)->next : terminate_invalid_parameter_count(inst);
  	}
  	return (code);
  }
  
  int8_t	get_one_arg(t_pars *pars, t_entity **curr, t_inst *inst, int arg_num)
  {
  	int8_t	class;
  
  	class = get_arg_type((*curr)->class);
  	if ((inst->args_classes[arg_num] & class) == 0)
  		terminate_invalid_argument(inst, arg_num, *curr);
  	if (class == T_REG)
  		proc_reg(pars, (*curr)->content + 1);
  	if ((*curr)->class == DIRECT_LABEL || (*curr)->class == INDIRECT_LABEL)
  		proc_mention(pars, *curr, inst);
  	if ((*curr)->class == DIRECT || (*curr)->class == INDIRECT)
  		proc_int(pars, *curr, inst);
  	return (class);
  }
  
  void	proc_reg(t_pars *pars, char *reg_number)
  {
  	write_to_bytecode(pars->code, pars->pos, ft_atoi(reg_number), 1);
  	++(pars->pos);
  }
  
  void	proc_mention(t_pars *pars, t_entity *curr, t_inst *inst)
  {
  	t_label *label;
  	char	*name;
  	int		start;
  	size_t	size;
  
  	start = (curr->class == INDIRECT_LABEL) ? 1 : 2;
  	size = (curr->class == INDIRECT_LABEL) ? IND_SIZE : inst->t_dir_size;
  	if (!(name = ft_strsub(curr->content, start,
  					ft_strlen(curr->content) - start)))
  		terminate(MEMORY_ALLOCATION);
  	if (!(label = find_label(pars->labels, name)))
  	{
  		label = new_label(-1, name);
  		add_label(&(pars->labels), label);
  	}
  	add_mention(&(label->mentions), new_mention(pars, curr, size));
  	pars->pos += size;
  	ft_strdel(&name);
  }
  
  void	proc_int(t_pars *pars, t_entity *curr, t_inst *inst)
  {
  	int		start;
  	size_t	size;
  
  	start = (curr->class == INDIRECT) ? 0 : 1;
  	size = (curr->class == INDIRECT) ? IND_SIZE : inst->t_dir_size;
  	write_to_bytecode(pars->code, pars->pos,
  					ft_atoi32(&(curr->content[start])), size);
  	pars->pos += size;
  }
  