Beispiel #1
0
char *tl_expression_join (struct tl_compiler *C, struct tl_expression *E, int output_magic) {
  struct tl_token *T;
  struct tl_buffer b;
  tl_string_buffer_init (&b);
  for (T = E->left; T != NULL; T = T->next) {
    if (b.pos) {
      tl_string_buffer_append_char (&b, ' ');
    }
    tl_string_buffer_append_cstr (&b, T->text);
    if (output_magic && T == E->left) {
      tl_string_buffer_printf (&b, "#%x", E->magic);
    }
  }
  if (E->right) {
    tl_string_buffer_append_char (&b, ' ');
    tl_string_buffer_append_char (&b, '=');
    for (T = E->right; T != NULL; T = T->next) {
      tl_string_buffer_append_char (&b, ' ');
      tl_string_buffer_append_cstr (&b, T->text);
    }
  }
  tl_string_buffer_append_char (&b, 0);
  int r = tl_expression_remove_sugar (C, E, b.buff);
  if (r < 0) {
    tl_string_buffer_free (&b);
    return NULL;
  }
  char *res = cstr_dup (b.buff);
  tl_string_buffer_free (&b);
  return res;
}
Beispiel #2
0
struct tl_token *tl_expresion_split (struct tl_compiler *C, struct tl_expression *E, const char *const expression, int remove_sugar) {
  int l = strlen (expression) + 1;
  char *s = zmalloc (l);
  strcpy (s, expression);

  if (remove_sugar) {
    if (tl_expression_remove_sugar (C, E, s) < 0) {
      return NULL;
    }
  }

  char *p;
  struct tl_token *head = NULL;
  for (p = strtok (s, " "); p != NULL; p = strtok (NULL, " ")) {
    struct tl_token *T = zmalloc0 (sizeof (struct tl_token));

#define ZHUKOV_BYTES_HACK
#ifdef ZHUKOV_BYTES_HACK
    /* dirty hack for Zhukov request */
    if (!strcmp (p, "bytes")) {
      T->text = cstr_dup ("string");
    } else if (!strcmp (p, "Bytes")) {
      T->text = cstr_dup ("String");
    } else {
      int l = strlen (p);
      if (l >= 6 && !strcmp (p + l - 6, ":bytes")) {
        T->text = zmalloc (l + 2);
        strcpy (T->text, p);
        strcpy (T->text + l - 6, ":string");
      } else if (l >= 6 && !strcmp (p + l - 6, ":Bytes")) {
        T->text = zmalloc (l + 2);
        strcpy (T->text, p);
        strcpy (T->text + l - 6, ":String");
      } else {
        T->text = cstr_dup (p);
      }
    }
#else
    T->text = cstr_dup (p);
#endif
    T->next = head;
    head = T;
  }
  zfree (s, l);
  return list_token_reverse (head);
}
Beispiel #3
0
static struct tl_token *tl_token_clone (struct tl_token *T) {
  struct tl_token *head = NULL;
  while (T != NULL) {
    struct tl_token *A = zmalloc0 (sizeof (struct tl_token));
    A->text = cstr_dup (T->text);
    A->next = head;
    head = A;
    T = T->next;
  }
  return list_token_reverse (head);
}
Beispiel #4
0
static void tl_add_expression (struct tl_compiler *C, int section, const char *text) {
  vkprintf (3, "tl_add_expression (section:%d, text:%s)\n", section, text);
  assert (section >= 0 && section < 2);
  struct tl_expression *E = zmalloc0 (sizeof (struct tl_expression));
  E->section = section;
  E->flag_builtin = C->flag_reading_builtin_schema;
  struct tl_expression *L = &C->expr[section];
  E->text = cstr_dup (text);
  struct tl_expression *A = L->prev;
  A->next = E; E->prev = A;
  E->next = L; L->prev = E;
}
Beispiel #5
0
char *cstr_join_with_sugar (struct tl_token *T) {
  int i, n, l;
  tl_token_length (T, &n, &l);
  assert (n >= 1);
  if (n == 1) {
    return cstr_dup (T->text);
  }
  l += n + 1;
  char *buf = tl_zzmalloc (l), *p = buf;
  for (i = 0; T != NULL; T = T->next, i++) {
    p += sprintf (p, "%s", T->text);
    *p++ = i ? ((i == n - 1) ? '>' : ',') : '<';
  }
  *p++ = 0;
  assert (p == buf + l);
  return buf;
}
Beispiel #6
0
void tl_expression_expand (struct tl_expression *E, struct tl_expression *R) {
  assert (R->type == tlet_polymorphic);
  assert (E->type == tlet_polymorphic_instance);
  struct tl_token *L = tl_token_clone (R->left);
  struct tl_token *x, *y, *z;
  for (x = L->next; x != NULL; x = x->next) {
    for (y = R->right->next, z = E->left->next; y != NULL; y = y->next, z = z->next) {
      if (!strcmp (x->text, y->text)) {
        cstr_free (&x->text);
        x->text = cstr_dup (z->text);
      }
    }
  }
  E->right = E->left;
  E->left = L;
  E->type = tlet_simple;
  E->right_name = cstr_join_with_sugar (E->right);
  E->flag_expanded = 1;
}
Beispiel #7
0
struct token token_stream_read(struct token_stream * ts)
{
	if(ts->end)
		return token_new(TOKEN_TYPE_END);
	enum states{
		READ_NEXT = 0,
		SCAN, SCAN_ERR,
		BUILD_SECTION, BUILD_SECTION1, BUILD_SECTION_END,
		BUILD_NAME, BUILD_NAME1, BUILD_NAME_END,
		BUILD_ASSIGNMENT,
		BUILD_STRING, BUILD_STRING1, BUILD_STRING_END,
		BUILD_COMMENT,
		BUILD_NEWLINE,
		BUILD_END,
		ERROR,
		SKIP_LINE,
	} state = ts->next_state;
	
	struct varstr * buf = varstr_new();
	struct char_stream * cs = ts->cs;
	struct token tok;
	int running = 1;
	do switch(state){
	case READ_NEXT:
		next_char(cs);
		
		state = SCAN;
	case SCAN:
		if(!cs->escaped)
		{
			if(cs->c == ' ' || cs->c == '\t')
				state = READ_NEXT;
			else if(cs->c == '[')
				state = BUILD_SECTION;
			else if(char_is_name(cs))
				state = BUILD_NAME;
			else if(cs->c == '=')
				state = BUILD_ASSIGNMENT;
			else if(cs->c == '"')
				state = BUILD_STRING;
			else if(cs->c == '#')
				state = BUILD_COMMENT;
			else if(cs->c == '\n')
				state = BUILD_NEWLINE;
			else if(cs->c == EOF)
				state = BUILD_END;
			else
				state = SCAN_ERR;
		}
		else
			state = SCAN_ERR;
		break;
	case SCAN_ERR:
		fprintf(stderr,"next_token: "
			"bad token at row %d, column %d\n",
			cs->row, cs->col);
		state = SKIP_LINE;
		break;

	case BUILD_SECTION:
		// [section]
		varstr_clear(buf);
		tok = token_new(TOKEN_TYPE_SECTION);
		state = BUILD_SECTION1;
	case BUILD_SECTION1:
		next_char(cs);
		if(char_is_name(cs))
			varstr_append(buf, cs->c);
		else
			state = BUILD_SECTION_END;
		break;
	case BUILD_SECTION_END:
		if(cs->c == ']' && !cs->escaped)
		{
			ts->next_state = READ_NEXT;
			tok.text = cstr_dup(varstr_view(buf));
			running = 0;
		}
		else
		{
			fprintf(stderr, "next_token: "
				"bad section name at row %d, column %d, "
				"expected ']'\n",
				cs->row, cs->col);
			state = ERROR;
		}
		break;
	case BUILD_NAME:
		// name
		tok = token_new(TOKEN_TYPE_NAME);
		varstr_clear(buf);
		varstr_append(buf, cs->c);
		state = BUILD_NAME1;
	case BUILD_NAME1:
		next_char(cs);
		if(char_is_name(cs))
			varstr_append(buf, cs->c);
		else
			state = BUILD_NAME_END;
		break;
	case BUILD_NAME_END:
		ts->next_state = SCAN;
		tok.text = cstr_dup(varstr_view(buf));
		running = 0;
		break;
	case BUILD_ASSIGNMENT:
		// =
		tok = token_new(TOKEN_TYPE_ASSIGNMENT);
		ts->next_state = READ_NEXT;
		running = 0;
		break;
	case BUILD_STRING:
		/* "multi
			line
				string
					with escape /"/n"
		*/
		tok = token_new(TOKEN_TYPE_STRING);
		varstr_clear(buf);
		state = BUILD_STRING1;
	case BUILD_STRING1:
		next_char(cs);
		if(cs->c == EOF)
			state = BUILD_STRING_END;
		else if(cs->c == '"' && !cs->escaped)
			state = BUILD_STRING_END;
		else
			varstr_append(buf, cs->c);
		break;
	case BUILD_STRING_END:
		if(cs->c == '"' && !cs->escaped)
		{
			ts->next_state = READ_NEXT;
			tok.text = cstr_dup(varstr_view(buf));
			running = 0;
		}
		else if(cs->c == EOF)
		{
			fprintf(stderr, "next_token"
				"bad string at row %d, column %d, "
				"expected '\"'\n",
				cs->row, cs->col);
			state = ERROR;
		}
		break;
	case BUILD_COMMENT:
		// # comment
		state = SKIP_LINE;
		break;
	case BUILD_NEWLINE:
		tok = token_new(TOKEN_TYPE_NEWLINE);
		ts->next_state = READ_NEXT;
		running = 0;
		break;
	case BUILD_END:
		tok = token_new(TOKEN_TYPE_NEWLINE);
		ts->end = 1;
		running = 0;
		break;
	case ERROR:
		state = SKIP_LINE;
	case SKIP_LINE:
		if(cs->c == '\n' && !cs->escaped)
			state = BUILD_NEWLINE;
		else if(cs->c == EOF)
			state = BUILD_END;
		else
			next_char(cs);
		break;
	}while(running);
	varstr_del(buf);
	return tok;
}