/***************************************************************************
                          assemble.c  -  Assembles the parsed lines
                             -------------------
    Date                : May 24 2000
    Copyright            : (C) 2000 by Daniel Bertrand
    Email                : d.bertrand@ieee.ca
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include<string.h>
#include<stdio.h>
#include"global.h"
#include<stdlib.h>
#include"compiler.h"

int source_line_num;

int operand_decode(char *operand);
/*
the op code is known
the operands are not parsed,they are stored as strings (incase some are symbols)
so we need to "decode" the operands and call OP for each line.
*/

void assemble(void)
{
	
	int i;
	extern struct parsed_struct parsed[DSP_CODE_SIZE];		
	extern int dsp_addr;
        
        //oops, discovered a bug which causes the assembler to segfault if there are less than 4 operands
	//I need to add a check for that somewhere here:

        for(i=0;i<dsp_addr;i++){
		source_line_num=parsed[i].source_line; //for asm debugging
	
		OP(parsed[i].op_number,
		operand_decode(strtok(NULL,", \t\n\0")),
		operand_decode(strtok(NULL,",")),
		operand_decode(strtok(NULL,",")),
		operand_decode(strtok((char *) &parsed[i].operand,",") ));
	}
}





/*
here's were we decode the operands
*/

//this returns "int" values, but with DC we need "long", need to fix it.

int operand_decode(char *operand)
{
	
	int i;
	extern int symbol_count;
	extern struct symbol sym_table[max_num_symbol];
	
	
	//hex operand:
	if((char)(*operand)=='$')
		return((int)strtol((operand+1),NULL,16));

	//octal operand:	
	if((char)(*operand)=='@')
		return((int)strtol(operand,NULL,8));
	
	//decimal operand:  		
	if( ((*operand) >= '0' && (*operand) <='9') ||(*operand)=='-')
  		return((int)strtol(operand,NULL,10));

	//check if it's a symbol:  			
	for(i=0;i<symbol_count;i++){
		if(strcmp((char *)&sym_table[i].name,operand)==0)
	 	break;
	}
	
	//not a symbol, it's a bad operand		
	if(strcmp((char *)&sym_table[i].name,operand)!=0){
		 fprintf(stderr,"Error: illegal operand \"%s\"on line number %d\n",operand,source_line_num);
		 illegal("Unrecoverable Error");
	}
		 		

  	return(sym_table[i].value);

}











