OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [Open8 Tools/] [open8_src/] [open8_as/] [parse.c] - Rev 319

Go to most recent revision | Compare with Previous | Blame | View Log

 
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "defines.h"
 
#include "parse.h"
#include "pass_1.h"
#include "stack.h"
 
 
int input_number_error_msg = YES, ss, string_size, input_float_mode = OFF, parse_floats = YES;
int newline_beginning = ON;
char label[MAX_NAME_LENGTH], xyz[256];
char unevaluated_expression[256];
char expanded_macro_string[256];
double flo;
 
extern int i, size, d, macro_active;
extern char *buffer, tmp[4096], cp[256];
extern struct active_file_info *active_file_info_first, *active_file_info_last, *active_file_info_tmp;
extern struct definition *defines, *tmp_def, *next_def;
extern struct macro_runtime *macro_runtime_current;
extern int latest_stack;
 
int operand_hint;
 
 
int compare_next_token(char *in, int s) {
 
  int a, t, d, k;
  char e;
 
 
  a = i;
  for (e = buffer[a]; e == ' ' || e == ',' || e == 0x0A; e = buffer[++a]);
 
  /* MACRO mode? */
  if (macro_active != 0 && e == '\\') {
    for (d = 0, k = 0; k < 16; k++) {
      e = buffer[++a];
      if (e >= '0' && e <= '9')
	d = (d * 10) + e - '0';
      else
	break;
    }
 
    if (d > macro_runtime_current->supplied_arguments) {
      if (input_number_error_msg == YES) {
	sprintf(xyz, "COMPARE_NEXT_SYMBOL: Macro \"%s\" wasn't called with enough arguments.\n", macro_runtime_current->macro->name);
	print_error(xyz, ERROR_NONE);
      }
      return FAILED;
    }
 
    a = macro_runtime_current->argument_data[d - 1]->start;
 
    e = buffer[a];
    for (t = 0; t < s && e != ' ' && e != ',' && e != 0x0A; ) {
      if (toupper(in[t]) != toupper(e))
	return FAILED;
      t++;
      e = buffer[++a];
    }
  }
  /* not in MACRO mode */
  else {
    for (t = 0; t < s && e != ' ' && e != ',' && e != 0x0A; ) {
      if (toupper(in[t]) != toupper(e))
	return FAILED;
      t++;
      e = buffer[++a];
    }
  }
 
  if (t == s)
    return SUCCEEDED;
  else
    return FAILED;
}
 
 
int input_next_string(void) {
 
  char e;
  int k, d;
 
 
  for (e = buffer[i++]; e == ' ' || e == ','; e = buffer[i++]);
 
  if (e == 0x0A)
    return INPUT_NUMBER_EOL;
 
  /* last choice is a label */
  tmp[0] = e;
  for (k = 1; k < MAX_NAME_LENGTH - 1; k++) {
    e = buffer[i++];
    if (e == 0x0A || e == ',') {
      i--;
      break;
    }
    else if (e == ' ')
      break;
    tmp[k] = e;
  }
 
  if (k == MAX_NAME_LENGTH - 1) {
    if (input_number_error_msg == YES) {
      sprintf(xyz, "The string is too long (max %d bytes).\n", MAX_NAME_LENGTH - 1);
      print_error(xyz, ERROR_NUM);
    }
    return FAILED;
  }
 
  tmp[k] = 0;
 
  /* expand eg. \1 and \@ */
  if (macro_active != 0) {
    d = 0;
    if (expand_macro_arguments(tmp, &d) == FAILED)
      return FAILED;
    if (d != 0)
      strcpy(tmp, expanded_macro_string);
  }
 
  return SUCCEEDED;
}
 
 
int input_number(void) {
 
  unsigned char e, ee;
  int k, p, q;
  double dn;
 
 
  operand_hint = HINT_NONE;
 
  for (e = buffer[i++]; e == ' ' || e == ','; e = buffer[i++]);
 
  if (e == 0x0A)
    return INPUT_NUMBER_EOL;
 
  /* check the type of the expression */
  p = i;
  ee = e;
  while (ee != 0x0A) {
    /* string / symbol -> no calculating */
    if (ee == '"' || ee == ',' || (ee == '=' && buffer[p] == '=') ||
	(ee == '!' && buffer[p] == '='))
      break;
    if (ee == '-' || ee == '+' || ee == '*' || ee == '/' || ee == '&' || ee == '|' || ee == '^' ||
	ee == '<' || ee == '>' || ee == '#' || ee == '~') {
      /* launch stack calculator */
      p = stack_calculate(&buffer[i - 1], &d);
      if (p == STACK_CALCULATE_DELAY)
	break;
      else if (p == STACK_RETURN_LABEL)
	return INPUT_NUMBER_ADDRESS_LABEL;
      else
	return p;
    }
    ee = buffer[p];
    p++;
  }
 
  /* MACRO */
  if (macro_active != 0 && e == '\\') {
 
    struct macro_argument *ma;
 
 
    if (buffer[i] == '@') {
      i++;
      d = macro_runtime_current->macro->calls - 1;
      return SUCCEEDED;
    }
 
    for (d = 0, k = 0; k < 4; k++) {
      e = buffer[i++];
      if (e >= '0' && e <= '9')
        d = (d * 10) + (e - '0');
      else {
        i--;
        break;
      }
    }
 
    if (d > macro_runtime_current->supplied_arguments) {
      sprintf(xyz, "Referencing argument number %d inside macro \"%s\". The macro has only %d arguments.\n", d, macro_runtime_current->macro->name, macro_runtime_current->supplied_arguments);
      print_error(xyz, ERROR_NUM);
      return FAILED;
    }
 
    /* return the macro argument */
    ma = macro_runtime_current->argument_data[d - 1];
    k = ma->type;
 
    if (k == INPUT_NUMBER_ADDRESS_LABEL)
      strcpy(label, ma->string);
    else if (k == INPUT_NUMBER_STRING) {
      strcpy(label, ma->string);
      string_size = strlen(ma->string);
    }
    else if (k == INPUT_NUMBER_STACK)
      latest_stack = ma->value;
    else if (k == SUCCEEDED)
      d = ma->value;
    else {
      print_error("Macro argument list has been corrupted! Please send a bug report!\n", ERROR_ERR);
      return FAILED;
    }
 
    return k;
  }
 
  /* is it a hexadecimal value? */
  d = 0;
  if (e >= '0' && e <= '9') {
    for (k = 0; 1; k++) {
      if (buffer[i+k] >= '0' && buffer[i+k] <= '9')
	continue;
      if (buffer[i+k] >= 'a' && buffer[i+k] <= 'f')
	continue;
      if (buffer[i+k] >= 'A' && buffer[i+k] <= 'F')
	continue;
      if (buffer[i+k] == 'h' || buffer[i+k] == 'H') {
	d = 1;
	break;
      }
      break;
    }
  }
 
  if (e == '$' || d == 1) {
    if (d == 1)
      i--;
    for (d = 0, k = 0; k < 8; k++, i++) {
      e = buffer[i];
      if (e >= '0' && e <= '9')
	d = (d << 4) + e - '0';
      else if (e >= 'A' && e <= 'F')
	d = (d << 4) + e - 'A' + 10;
      else if (e >= 'a' && e <= 'f')
	d = (d << 4) + e - 'a' + 10;
      else if (e == 'h' || e == 'H') {
	i++;
	e = buffer[i];
	break;
      }
      else
	break;
    }
 
    if (e == '.') {
      e = buffer[i+1];
      if (e == 'b' || e == 'B') {
	operand_hint = HINT_8BIT;
	i += 2;
      }
      else if (e == 'w' || e == 'W') {
	operand_hint = HINT_16BIT;
	i += 2;
      }
    }
 
    return SUCCEEDED;
  }
 
  if (e >= '0' && e <= '9') {
    q = 0;
    flo = e-'0';
    dn = 0.1;
    for (k = 0; k < 9; k++, i++) {
      e = buffer[i];
      if (e >= '0' && e <= '9') {
	if (q == 0) {
	  /* still parsing an integer */
	  flo = flo*10 + e-'0';
	}
	else {
	  flo = flo + dn*(e-'0');
	  dn /= 10.0;
	}
      }
      else if (e == '.') {
	if (q == 1) {
	  print_error("Syntax error.\n", ERROR_NUM);
	  return FAILED;
	}
	e = buffer[i+1];
	if (e >= '0' && e <= '9') {
	  /* float mode, read decimals */
	  if (parse_floats == NO)
	    break;
	  q = 1;
	}
	else if (e == 'b' || e == 'B') {
	  operand_hint = HINT_8BIT;
	  i += 2;
	  break;
	}
	else if (e == 'w' || e == 'W') {
	  operand_hint = HINT_16BIT;
	  i += 2;
	  break;
	}
      }
      else
	break;
    }
 
    /* drop the decimals */
    d = flo;
 
    if (q == 1 && input_float_mode == ON)
      return INPUT_NUMBER_FLOAT;
 
    return SUCCEEDED;
  }
 
  if (e == '%') {
    for (d = 0, k = 0; k < 32; k++, i++) {
      e = buffer[i];
      if (e == '0' || e == '1')
	d = (d << 1) + e - '0';
      else
	break;
    }
 
    if (e == '.') {
      e = buffer[i+1];
      if (e == 'b' || e == 'B') {
	operand_hint = HINT_8BIT;
	i += 2;
      }
      else if (e == 'w' || e == 'W') {
	operand_hint = HINT_16BIT;
	i += 2;
      }
    }
 
    return SUCCEEDED;
  }
 
  if (e == '\'') {
    d = buffer[i++];
    e = buffer[i];
    if (e != '\'') {
      if (input_number_error_msg == YES) {
	sprintf(xyz, "Got '%c' (%d) when expected \"'\".\n", e, e);
	print_error(xyz, ERROR_NUM);
      }
      return FAILED;
    }
    i++;
 
    return SUCCEEDED;
  }
 
  if (e == '"') {
 
    for (k = 0; k < MAX_NAME_LENGTH - 1; ) {
      e = buffer[i++];
 
      if (e == '\\' && buffer[i] == '"') {
	label[k++] = '"';
	i++;
	continue;
      }
 
      if (e == '"')
	break;
 
      if (e == 0 || e == 0x0A) {
	print_error("String wasn't terminated properly.\n", ERROR_NUM);
	return FAILED;
      }
 
      label[k++] = e;
    }
 
    label[k] = 0;
 
    /* expand eg. \1 and \@ */
    if (macro_active != 0) {
      d = 0;
      if (expand_macro_arguments(label, &d) == FAILED)
	return FAILED;
      if (d != 0) {
	strcpy(label, expanded_macro_string);
	k = strlen(label);
      }
    }
 
    if (k == MAX_NAME_LENGTH - 1) {
      if (input_number_error_msg == YES) {
	sprintf(xyz, "The string is too long (max %d bytes).\n", MAX_NAME_LENGTH - 1);
	print_error(xyz, ERROR_NUM);
      }
      return FAILED;
    }
 
    label[k] = 0;
    string_size = k;
    return INPUT_NUMBER_STRING;
  }
 
  /* last choice is a label */
  label[0] = e;
  for (k = 1; k < MAX_NAME_LENGTH - 1; k++) {
    e = buffer[i++];
    if (e == 0x0A || e == ')' || e == ',' || e == ']') {
      i--;
      break;
    }
    else if (e == ' ')
      break;
    label[k] = e;
  }
 
  if (k == MAX_NAME_LENGTH - 1) {
    if (input_number_error_msg == YES) {
      sprintf(xyz, "The label is too long (max %d bytes).\n", MAX_NAME_LENGTH - 1);
      print_error(xyz, ERROR_NUM);
    }
    return FAILED;
  }
 
  /* size hint? */
  if (label[k-2] == '.') {
    if (label[k-1] == 'b' || label[k-1] == 'B') {
      operand_hint = HINT_8BIT;
      k -= 2;
    }
    else if (label[k-1] == 'w' || label[k-1] == 'W') {
      operand_hint = HINT_16BIT;
      k -= 2;
    }
  }
 
  label[k] = 0;
 
  /* expand eg. \1 and \@ */
  if (macro_active != 0) {
    d = 0;
    if (expand_macro_arguments(label, &d) == FAILED)
      return FAILED;
    if (d != 0)
      strcpy(label, expanded_macro_string);
  }
 
  /* check if the label is actually a definition */
  tmp_def = defines;
  while (tmp_def != NULL) {
    if (strcmp(label, tmp_def->alias) == 0) {
      if (tmp_def->type == DEFINITION_TYPE_VALUE) {
	d = tmp_def->value;
	return SUCCEEDED;
      }
      else if (tmp_def->type == DEFINITION_TYPE_STACK) {
	/* skip stack definitions -> use its name instead */
      }
      else {
	string_size = tmp_def->size;
	memcpy(label, tmp_def->string, string_size);
	label[string_size] = 0;
	return INPUT_NUMBER_STRING;
      }
    }
    tmp_def = tmp_def->next;
  }
 
  return INPUT_NUMBER_ADDRESS_LABEL;
}
 
 
int get_next_token(void) {
 
  int q;
 
 
  while (1) {
    if (i == size)
      break;
    if (buffer[i] == ' ') {
      i++;
      newline_beginning = OFF;
      continue;
    }
    if (buffer[i] == 0x0A) {
      i++;
      next_line();
      continue;
    }
    break;
  }
 
  if (buffer[i] == '"') {
    for (ss = 0, i++; buffer[i] != 0x0A && buffer[i] != '"'; ) {
      if (buffer[i] == '\\' && buffer[i + 1] == '"') {
	tmp[ss++] = '"';
	i += 2;
      }
      else
	tmp[ss++] = buffer[i++];
    }
 
    if (buffer[i] == 0x0A) {
      print_error("GET_NEXT_TOKEN: String wasn't terminated properly.\n", ERROR_NONE);
      return FAILED;
    }
    tmp[ss] = 0;
    i++;
 
    /* expand eg. \1 and \@ */
    if (macro_active != 0) {
      q = 0;
      if (expand_macro_arguments(tmp, &q) == FAILED)
	return FAILED;
      if (q != 0) {
	strcpy(tmp, expanded_macro_string);
	ss = strlen(tmp);
      }
    }
 
    return GET_NEXT_TOKEN_STRING;
  }
 
  if (buffer[i] == '.') {
    tmp[0] = '.';
    i++;
    for (ss = 1; buffer[i] != 0x0A && buffer[i] != ' ' && ss <= MAX_NAME_LENGTH; ) {
      tmp[ss] = buffer[i];
      cp[ss - 1] = toupper((int)buffer[i]);
      i++;
      ss++;
    }
    cp[ss - 1] = 0;
  }
  else if (buffer[i] == '=' || buffer[i] == '>' || buffer[i] == '<' || buffer[i] == '!') {
    for (ss = 0; buffer[i] != 0x0A && (buffer[i] == '=' || buffer[i] == '!' || buffer[i] == '<' || buffer[i] == '>')
	   && ss <= MAX_NAME_LENGTH; tmp[ss++] = buffer[i++]);
  }
  else {
    for (ss = 0; buffer[i] != 0x0A && buffer[i] != ',' && buffer[i] != ' ' && ss <= MAX_NAME_LENGTH; ) {
      tmp[ss] = buffer[i];
      ss++;
      i++;
    }
    if (buffer[i] == ',')
      i++;
  }
 
  if (ss > MAX_NAME_LENGTH) {
    print_error("GET_NEXT_TOKEN: Too long for a token.\n", ERROR_NONE);
    return FAILED;
  }
 
  tmp[ss] = 0;
 
  /* expand eg. \1 and \@ */
  if (macro_active != 0) {
    q = 0;
    if (expand_macro_arguments(tmp, &q) == FAILED)
      return FAILED;
    if (q != 0) {
      strcpy(tmp, expanded_macro_string);
      ss = strlen(tmp);
    }
  }
 
  return SUCCEEDED;
}
 
 
int skip_next_token(void) {
 
  for (; buffer[i] == ' ' || buffer[i] == ','; i++);
 
  if (buffer[i] == 0x0A)
    return FAILED;
 
  if (buffer[i] == '"') {
    for (i++; buffer[i] != 0x0A && buffer[i] != '"'; i++);
    if (buffer[i] == 0x0A) {
      print_error("SKIP_NEXT_TOKEN: String wasn't terminated properly.\n", ERROR_NONE);
      return FAILED;
    }
    i++;
 
    return SUCCEEDED;
  }
 
  for (; buffer[i] != 0x0A && buffer[i] != ' ' && buffer[i] != ','; i++);
 
  return SUCCEEDED;
}
 
 
int expand_macro_arguments(char *in, int *s) {
 
  char t[256];
  int i, k, d;
 
 
  for (i = 0; i < MAX_NAME_LENGTH; i++) {
    if (in[i] == '\\') {
      if (in[i + 1] == '"' || in[i + 1] == 'n' || in[i + 1] == '\\') {
	expanded_macro_string[i] = in[i];
	i++;
	expanded_macro_string[i] = in[i];
	continue;
      }
      break;
    }
    expanded_macro_string[i] = in[i];
    if (in[i] == 0)
      return SUCCEEDED;
  }
 
  k = i;
  i++;
 
  (*s)++;
 
  if (in[i] == '@') {
    i++;
    sprintf(&expanded_macro_string[k], "%d%c", macro_runtime_current->macro->calls - 1, 0);
    k = strlen(expanded_macro_string);
 
    for (; i < MAX_NAME_LENGTH; i++, k++) {
      expanded_macro_string[k] = in[i];
      if (in[i] == 0) {
	break;
      }
    }
 
    strcpy(t, expanded_macro_string);
    expand_macro_arguments(t, &d);
    return SUCCEEDED;
  }
 
  if (in[i] <= '0' || in[i] >= '9') {
    if (input_number_error_msg == YES) {
      sprintf(xyz, "EXPAND_MACRO_ARGUMENTS: Unsupported special character '%c'.\n", in[i]);
      print_error(xyz, ERROR_NUM);
    }
    return FAILED;
  }
 
  for (d = 0; in[i] != 0; i++) {
    if (in[i] >= '0' && in[i] <= '9')
      d = (d * 10) + in[i] - '0';
    else
      break;
  }
 
  if (d > macro_runtime_current->supplied_arguments) {
    if (input_number_error_msg == YES) {
      sprintf(xyz, "Macro \"%s\" wasn't called with enough arguments.\n", macro_runtime_current->macro->name);
      print_error(xyz, ERROR_NUM);
    }
    return FAILED;
  }
 
  d = macro_runtime_current->argument_data[d - 1]->start;
 
  for (; k < MAX_NAME_LENGTH; d++, k++) {
    if (buffer[d] == 0 || buffer[d] == ' ' || buffer[d] == 0x0A || buffer[d] == ',')
      break;
    expanded_macro_string[k] = buffer[d];
  }
 
  for (; k < MAX_NAME_LENGTH; i++, k++) {
    expanded_macro_string[k] = in[i];
    if (in[i] == 0) {
      break;
    }
  }
 
  strcpy(t, expanded_macro_string);
  expand_macro_arguments(t, &d);
 
  return SUCCEEDED;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.