예제 #1
0
static void
advance_pos (TextgenTemplate *tpl,
             const gchar *text, 
             gint length,
             gint *pos,
             gint *line,
             gint *column,
             GError **error)
{
  const gchar *next_char = g_utf8_find_next_char (text + *pos, text + length + 1);
  
  if (!next_char)
    {
      emit_message (tpl, TEXTGEN_MESSAGE_ERROR, *line, *column,
                    _("Invalid UTF-8 character"));
      set_parse_error (error);
      return;
    }
  
  if (text[*pos] == '\n')
    {
      (*line)++;
      *column = 1;
    }
  else
    (*column)++;

  *pos = next_char - text;
}
예제 #2
0
파일: ast.hpp 프로젝트: bsurmanski/wlc
 virtual int64_t asInteger() {
     if(isConstant()) {
         VariableDeclaration *vdecl = id->getDeclaration()->variableDeclaration();
         if(vdecl && vdecl->value) {
             return vdecl->value->asInteger();
         }
     } else {
         emit_message(msg::ERROR, "attempt to convert non-const identifier to int", loc);
     }
     return 0;
 }
예제 #3
0
static void emit_log(struct lio *lio, char *key, char *val, char *key1, char *val1, char *key2, char *val2)
{
    char buf[128] = {};
    size_t len;
    len = emit_message(buf, LOGPOOL_EVENT_WRITE, 3,
            strlen(key), strlen(val), key, val,
            strlen(key1), strlen(val1), key1, val1,
            strlen(key2), strlen(val2), key2, val2,
            NULL);
    fprintf(stderr, "len=%zd, buf=%s\n", len, buf+LOG_PROTOCOL_SIZE*4);
    assert(lio_Write(lio, buf, len) == LIO_OK);
}
예제 #4
0
파일: ast.cpp 프로젝트: bsurmanski/wlc
Expression *Expression::coerceTo(ASTType *ty) {
    ASTType *expty = getType();

    if(expty->is(ty)) {
        return this;
    }

    if(coercesTo(ty)) {
        //TODO: note in AST that this is implicit
        return new CastExpression(ty, this, loc);
    }

    emit_message(msg::ERROR, "attempt to coerce expression of type '" + expty->getName() +
            "' to incompatible type '" + ty->getName() + "'", loc);

    return NULL;
}
예제 #5
0
static Node *
parse_list (TextgenTemplate *tpl,
            GList *tokens,
            CheckEndFunc check_end,
            GList **end, 
            GError **error)
{
  gboolean success = TRUE;
  GList *list = NULL;
  GList *l;

  l = tokens;
  while (l && !(check_end  && check_end (l)))
    {
      Token *token = l->data;
      
      if (token->type == TOKEN_TEXT)
        {
          Node *node;
          node = g_slice_new (Node);
          node->type = NODE_TEXT;
          node->value.text.text = token->content;
          node->value.text.length = token->content_length;
          token->owns_content = FALSE;

          list = g_list_prepend (list, node);
          l = l->next;
        }
      else if (token->type == TOKEN_VARIABLE)
        {
          Node *node;
          node = g_slice_new (Node);
          node->type = NODE_VARIABLE;
          node->value.variable.name = token->content;
          node->value.variable.line = token->line;
          node->value.variable.column = token->column;
          token->owns_content = FALSE;

          list = g_list_prepend (list, node);
          l = l->next;
        }
      else if (token->type == TOKEN_EXPRESSION
               || token->type == TOKEN_SCRIPT)
        {
          Node *node;
          node = g_slice_new (Node);
          node->type = token->type == TOKEN_EXPRESSION ? NODE_EXPRESSION 
                                                       : NODE_SCRIPT;
          node->value.script.code = token->content;
          node->value.script.length = token->content_length;
          node->value.script.code_line = token->line;
          node->value.script.code_column = token->content_column;
          token->owns_content = FALSE;

          list = g_list_prepend (list, node);
          l = l->next;
        }
      else if (token->type == TOKEN_COMMAND)
        {
          if (g_ascii_strcasecmp (token->command, "IF") == 0)
            {
              Node *node;
              GList *end;
              GError *tmp_error = NULL;
              
              node = parse_condition (tpl, l, &end, &tmp_error);
              if (tmp_error)
                {
                  g_propagate_error (error, tmp_error);
                  success = FALSE;
                  goto finish;
                }

              list = g_list_prepend (list, node);
              l = end->next;
            }
          else if (g_ascii_strcasecmp (token->command, "INCLUDE") == 0)
            {
              Node *node;
              node = g_slice_new (Node);
              node->type = NODE_INCLUDE;
              node->value.script.code = token->content;
              node->value.script.length = token->content_length;
              node->value.script.code_line = token->line;
              node->value.script.code_column = token->content_column;
              token->owns_content = FALSE;

              list = g_list_prepend (list, node);
              l = l->next;
            }
          else
            {
              emit_message (tpl, TEXTGEN_MESSAGE_ERROR, 
                             token->line, token->column,
                            _("Unknown command %s"), token->command);
              set_parse_error (error);
              success = FALSE;
              goto finish;
            }
        }
    }

  if (end)
    *end = l;

finish:
  if (success)
    {
      Node *node = g_slice_new (Node);
      node->type = NODE_LIST;
      node->value.list = g_list_reverse (list);
      return node;
    }
  else
    {
      g_list_free_full (list, free_node);
      return NULL;
    }
}
예제 #6
0
static Node *
parse_condition (TextgenTemplate *tpl,
                 GList *tokens,
                 GList **end, 
                 GError **error)
{
  Token *start_token = tokens->data;
  Token *end_token;
  gboolean success = TRUE;
  Node *if_true = NULL;
  Node *if_false = NULL;
  GList *tmp_end = NULL;
  GError *tmp_error = NULL;
  
  if_true = parse_list (tpl, tokens->next, check_condition_if_true_end, &tmp_end, &tmp_error);
  if (tmp_error != NULL)
    {
      success = FALSE;
      g_propagate_error (error, tmp_error);
      goto finish;
    }

  if (tmp_end == NULL)
    {
      emit_message (tpl, TEXTGEN_MESSAGE_ERROR, 
                    start_token->line, start_token->column,
                    _("Could not find ENDIF of the condition"));
      set_parse_error (error);
      success = FALSE;
      goto finish;
    }

  end_token = tmp_end->data;

  if (g_ascii_strcasecmp (end_token->command, "ELSEIF") == 0)
    {
      if_false = parse_condition (tpl, tmp_end, &tmp_end, &tmp_error);
      if (tmp_error)
        {
          g_propagate_error (error, tmp_error);
          success = FALSE;
          goto finish;
        }
    }
  else if (g_ascii_strcasecmp (end_token->command, "ELSE") == 0)
    {
      if_false = parse_list (tpl, tmp_end->next, check_condition_if_false_end, &tmp_end, &tmp_error);
      if (tmp_error)
        {
          g_propagate_error (error, tmp_error);
          success = FALSE;
          goto finish;
        }

      if (tmp_end == NULL)
        {
          emit_message (tpl, TEXTGEN_MESSAGE_ERROR, 
                        start_token->line, start_token->column,
                        _("Could not find ENDIF of the condition"));
          set_parse_error (error);
          success = FALSE;
          goto finish;
        }
    }

finish:
  if (success)
    {
      Node *node;
      node = g_slice_new (Node);
      node->type = NODE_CONDITION;
      node->value.cond.code = start_token->content;
      node->value.cond.length = start_token->content_length;
      node->value.cond.if_true = if_true;
      node->value.cond.if_false = if_false;
      node->value.cond.code_line = start_token->line;
      node->value.cond.code_column = start_token->column;
      start_token->owns_content = FALSE;
      *end = tmp_end;
      return node;
    }
  else
    {
      if (if_true) free_node (if_true);
      if (if_false) free_node (if_false);
      return FALSE;
    }
}
예제 #7
0
static Token *
maybe_parse_instruction (TextgenTemplate *tpl,
                         const gchar *text, 
                         gint length,
                         gint start,
                         gint start_line,
                         gint start_column,
                         gboolean *ignore_empty_line,
                         gint *after_end,
                         gint *after_end_line,
                         gint *after_end_column,
                         GError **error)
{
  gboolean success = TRUE;
  gboolean found_end = FALSE;
  gchar instr;
  gint content_offset;
  gchar *command = NULL;
  gchar *content = NULL;
  gint content_length;
  gint pos = start;
  gint cur_line = start_line;
  gint cur_column = start_column;
  GError *tmp_error = NULL;

  if (start < length - 1 && text[start] == '[')
    {
      if (text[start + 1] == '!')
        {
          *ignore_empty_line = TRUE;
          instr = text[start + 2];
          content_offset = 3;
        }
      else
        {
          *ignore_empty_line = FALSE;
          instr = text[start + 1];
          content_offset = 2;
        }
    
      if (!IS_VALID_INSTRUCTION_CHAR (instr))
        return NULL;
    }
  else
    return NULL;

  pos += content_offset;
  cur_column += content_offset;

  while (pos < length)
    {
      if (pos < length - 1 && text[pos] == instr && text[pos + 1] == ']')
        {
          gint content_start = start + content_offset;
          content_length = pos - content_start;
          content = g_strndup (text + content_start, content_length);
          *after_end = pos + 2;
          cur_column += 2;
          found_end = TRUE;
          break;
        }

      advance_pos (tpl, text, length, &pos, &cur_line, &cur_column, &tmp_error);
      if (tmp_error)
        {
          g_propagate_error (error, tmp_error);
          success = FALSE;
          goto finish;
        }
    }

  if (!found_end)
    {
      emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column,
                    _("Could not find the end of the instruction"), instr);
      set_parse_error (error);
      success = FALSE;
      goto finish;
    }

  if (instr == TOKEN_COMMAND)
    {
      static GRegex *regex = NULL;
      GMatchInfo *match_info;
      gchar *old_content = content;
      gint start_pos;
      gint end_pos;

      if (!regex)
        regex = g_regex_new ("^\\s*([A-Za-z]+)\\s+(.*)$", G_REGEX_MULTILINE | G_REGEX_OPTIMIZE, 0, NULL);

      if (!g_regex_match (regex, old_content, 0, &match_info))
        {
          emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column,
                        _("A command must look like this: [# COMMAND content #]"));
          set_parse_error (error);
          success = FALSE;
          goto finish;
        }

      command = g_match_info_fetch (match_info, 1);
      content = g_match_info_fetch (match_info, 2);

      g_match_info_fetch_pos (match_info, 2, &start_pos, &end_pos);
      content_length = end_pos - start_pos;
      
      g_match_info_free (match_info);
      g_free (old_content);
    }

  *after_end_line = cur_line;
  *after_end_column = cur_column;

finish:
  if (success)
    {
      Token *token = g_slice_new (Token);
      token->type = instr;
      token->command = command;
      token->content = content;
      token->content_length = content_length;
      token->line = start_line;
      token->column = start_column;
      token->content_column = start_column + content_offset;
      token->owns_content = TRUE;
      token->owns_command = TRUE;
      return token;
    }
  else
    {
      g_free (command);
      g_free (content);
      return NULL;
    }
}
예제 #8
0
파일: ast.hpp 프로젝트: bsurmanski/wlc
 virtual int64_t asInteger() {
     emit_message(msg::ERROR, "this value cannot be converted to integer", loc);
     return 0;
 }
예제 #9
0
파일: ast.hpp 프로젝트: bsurmanski/wlc
 virtual long getMemberIndex(std::string member) {
     emit_message(msg::FAILURE, "member index is meaningless for interface");
     return 0;
 }