Add human-readable syntax errors
This commit is contained in:
+11
-7
@@ -97,12 +97,16 @@ typedef enum
|
||||
*/
|
||||
extern uint32_t jerry_unreferenced_expression;
|
||||
|
||||
extern void __noreturn jerry_assert_fail (const char *assertion, const char *file, const uint32_t line);
|
||||
extern void __noreturn jerry_unreachable (const char *comment, const char *file, const uint32_t line);
|
||||
extern void __noreturn jerry_unimplemented (const char *comment, const char *file, const uint32_t line);
|
||||
extern void __noreturn jerry_assert_fail (const char *assertion, const char *file, const char *function,
|
||||
const uint32_t line);
|
||||
extern void __noreturn jerry_unreachable (const char *comment, const char *file, const char *function,
|
||||
const uint32_t line);
|
||||
extern void __noreturn jerry_unimplemented (const char *comment, const char *file, const char *function,
|
||||
const uint32_t line);
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
#define JERRY_ASSERT(x) do { if (__builtin_expect (!(x), 0)) { jerry_assert_fail (#x, __FILE__, __LINE__); } } while (0)
|
||||
#define JERRY_ASSERT(x) do { if (__builtin_expect (!(x), 0)) { \
|
||||
jerry_assert_fail (#x, __FILE__, __FUNCTION__, __LINE__); } } while (0)
|
||||
#else /* !JERRY_NDEBUG */
|
||||
#define JERRY_ASSERT(x) (void) (x)
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
@@ -114,19 +118,19 @@ extern void jerry_ref_unused_variables (int unused_variables_follow, ...);
|
||||
#define JERRY_UNREACHABLE() \
|
||||
do \
|
||||
{ \
|
||||
jerry_unreachable (NULL, __FILE__, __LINE__); \
|
||||
jerry_unreachable (NULL, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define JERRY_UNIMPLEMENTED() \
|
||||
do \
|
||||
{ \
|
||||
jerry_unimplemented (NULL, __FILE__, __LINE__); \
|
||||
jerry_unimplemented (NULL, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define JERRY_UNIMPLEMENTED_REF_UNUSED_VARS(...) \
|
||||
do \
|
||||
{ \
|
||||
jerry_unimplemented (NULL, __FILE__, __LINE__); \
|
||||
jerry_unimplemented (NULL, __FILE__, __FUNCTION__, __LINE__); \
|
||||
if (false) \
|
||||
{ \
|
||||
jerry_ref_unused_variables (0, __VA_ARGS__); \
|
||||
|
||||
+271
-307
@@ -19,12 +19,14 @@
|
||||
#include "parser.h"
|
||||
#include "stack.h"
|
||||
#include "opcodes.h"
|
||||
#include "parse-error.h"
|
||||
|
||||
static token saved_token, prev_token, sent_token;
|
||||
static token empty_token =
|
||||
{
|
||||
.type = TOK_EMPTY,
|
||||
.uid = 0
|
||||
.uid = 0,
|
||||
.locus = 0
|
||||
};
|
||||
|
||||
static bool allow_dump_lines = false;
|
||||
@@ -71,7 +73,6 @@ get_char (size_t i)
|
||||
return *(buffer + i);
|
||||
}
|
||||
|
||||
#ifdef __TARGET_HOST_x64
|
||||
static void
|
||||
dump_current_line (void)
|
||||
{
|
||||
@@ -90,7 +91,29 @@ dump_current_line (void)
|
||||
}
|
||||
__putchar ('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
static token
|
||||
create_token (token_type type, size_t loc __unused, uint8_t uid)
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = type,
|
||||
.locus = loc,
|
||||
.uid = uid
|
||||
};
|
||||
}
|
||||
|
||||
static token
|
||||
create_token_from_current_token (token_type type, uint8_t uid)
|
||||
{
|
||||
return create_token (type, (size_t) (token_start - buffer_start), uid);
|
||||
}
|
||||
|
||||
static token
|
||||
create_token_from_buffer_state (token_type type, uint8_t uid)
|
||||
{
|
||||
return create_token (type, (size_t) (buffer - buffer_start), uid);
|
||||
}
|
||||
|
||||
static bool
|
||||
current_token_equals_to (const char *str)
|
||||
@@ -128,371 +151,187 @@ decode_keyword (void)
|
||||
{
|
||||
if (current_token_equals_to ("break"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_BREAK
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_BREAK);
|
||||
}
|
||||
if (current_token_equals_to ("case"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_CASE
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_CASE);
|
||||
}
|
||||
if (current_token_equals_to ("catch"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_CATCH
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_CATCH);
|
||||
}
|
||||
if (current_token_equals_to ("class"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("const"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("continue"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_CONTINUE
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_CONTINUE);
|
||||
}
|
||||
if (current_token_equals_to ("debugger"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_DEBUGGER
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_DEBUGGER);
|
||||
}
|
||||
if (current_token_equals_to ("default"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_DEFAULT
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_DEFAULT);
|
||||
}
|
||||
if (current_token_equals_to ("delete"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_DELETE
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_DELETE);
|
||||
}
|
||||
if (current_token_equals_to ("do"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_DO
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_DO);
|
||||
}
|
||||
if (current_token_equals_to ("else"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_ELSE
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_ELSE);
|
||||
}
|
||||
if (current_token_equals_to ("enum"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("export"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("extends"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("false"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_BOOL,
|
||||
.uid = false
|
||||
};
|
||||
return create_token_from_current_token (TOK_BOOL, false);
|
||||
}
|
||||
if (current_token_equals_to ("finally"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_FINALLY
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_FINALLY);
|
||||
}
|
||||
if (current_token_equals_to ("for"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_FOR
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_FOR);
|
||||
}
|
||||
if (current_token_equals_to ("function"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_FUNCTION
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_FUNCTION);
|
||||
}
|
||||
if (current_token_equals_to ("if"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_IF
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_IF);
|
||||
}
|
||||
if (current_token_equals_to ("instanceof"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_INSTANCEOF
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_INSTANCEOF);
|
||||
}
|
||||
if (current_token_equals_to ("interface"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("in"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_IN
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_IN);
|
||||
}
|
||||
if (current_token_equals_to ("import"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("implements"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("let"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("new"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_NEW
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_NEW);
|
||||
}
|
||||
if (current_token_equals_to ("null"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NULL,
|
||||
.uid = 0
|
||||
};
|
||||
return create_token_from_current_token (TOK_NULL, 0);
|
||||
}
|
||||
if (current_token_equals_to ("package"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("private"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("protected"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("public"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("return"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RETURN
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RETURN);
|
||||
}
|
||||
if (current_token_equals_to ("static"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("super"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("switch"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_SWITCH
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_SWITCH);
|
||||
}
|
||||
if (current_token_equals_to ("this"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_THIS
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_THIS);
|
||||
}
|
||||
if (current_token_equals_to ("throw"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_THROW
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_THROW);
|
||||
}
|
||||
if (current_token_equals_to ("true"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_BOOL,
|
||||
.uid = true
|
||||
};
|
||||
return create_token_from_current_token (TOK_BOOL, true);
|
||||
}
|
||||
if (current_token_equals_to ("try"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_TRY
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_TRY);
|
||||
}
|
||||
if (current_token_equals_to ("typeof"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_TYPEOF
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_TYPEOF);
|
||||
}
|
||||
if (current_token_equals_to ("var"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_VAR
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_VAR);
|
||||
}
|
||||
if (current_token_equals_to ("void"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_VOID
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_VOID);
|
||||
}
|
||||
if (current_token_equals_to ("while"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_WHILE
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_WHILE);
|
||||
}
|
||||
if (current_token_equals_to ("with"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_WITH
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_WITH);
|
||||
}
|
||||
if (current_token_equals_to ("yield"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_KEYWORD,
|
||||
.uid = KW_RESERVED
|
||||
};
|
||||
return create_token_from_current_token (TOK_KEYWORD, KW_RESERVED);
|
||||
}
|
||||
if (current_token_equals_to ("undefined"))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_UNDEFINED,
|
||||
.uid = 0
|
||||
};
|
||||
return create_token_from_current_token (TOK_UNDEFINED, 0);
|
||||
}
|
||||
return empty_token;
|
||||
}
|
||||
@@ -506,11 +345,7 @@ convert_current_token_to_token (token_type tt)
|
||||
{
|
||||
if (current_token_equals_to_lp (STACK_ELEMENT (strings, i)))
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = tt,
|
||||
.uid = i
|
||||
};
|
||||
return create_token_from_current_token (tt, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,11 +357,7 @@ convert_current_token_to_token (token_type tt)
|
||||
|
||||
STACK_PUSH (strings, str);
|
||||
|
||||
return (token)
|
||||
{
|
||||
.type = tt,
|
||||
.uid = (idx_t) (STACK_SIZE (strings) - 1)
|
||||
};
|
||||
return create_token_from_current_token (tt, (idx_t) (STACK_SIZE (strings) - 1));
|
||||
}
|
||||
|
||||
static token
|
||||
@@ -539,11 +370,7 @@ convert_seen_num_to_token (ecma_number_t num)
|
||||
{
|
||||
if (STACK_ELEMENT (numbers, i) == num)
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = STACK_ELEMENT (num_ids, i)
|
||||
};
|
||||
return create_token_from_current_token (TOK_NUMBER, STACK_ELEMENT (num_ids, i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,11 +378,7 @@ convert_seen_num_to_token (ecma_number_t num)
|
||||
STACK_PUSH (num_ids, num_id);
|
||||
STACK_PUSH (numbers, num);
|
||||
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = num_id
|
||||
};
|
||||
return create_token_from_current_token (TOK_NUMBER, num_id);
|
||||
}
|
||||
|
||||
const lp_string *
|
||||
@@ -635,11 +458,7 @@ consume_char (void)
|
||||
do \
|
||||
{ \
|
||||
buffer += NUM; \
|
||||
return (token) \
|
||||
{ \
|
||||
.type = TOK, \
|
||||
.uid = 0 \
|
||||
}; \
|
||||
return create_token_from_buffer_state (TOK, 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -803,7 +622,7 @@ parse_number (void)
|
||||
|
||||
if (__isalpha (c) || c == '_' || c == '$')
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit characters", buffer - buffer_start);
|
||||
}
|
||||
|
||||
tok_length = (size_t) (buffer - token_start);
|
||||
@@ -820,20 +639,18 @@ parse_number (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
token_start = NULL;
|
||||
|
||||
if (res <= 255)
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_SMALL_INT,
|
||||
.uid = (uint8_t) res
|
||||
};
|
||||
known_token = create_token_from_current_token (TOK_SMALL_INT, (uint8_t) res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
known_token = convert_seen_num_to_token ((ecma_number_t) res);
|
||||
JERRY_ASSERT (!is_empty (known_token));
|
||||
|
||||
token_start = NULL;
|
||||
|
||||
return known_token;
|
||||
}
|
||||
|
||||
@@ -852,18 +669,20 @@ parse_number (void)
|
||||
c = LA (0);
|
||||
if (is_fp && c == '.')
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain more than one dot character", buffer - buffer_start);
|
||||
}
|
||||
if (is_exp && (c == 'e' || c == 'E'))
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain more than exponential marker ('e' or 'E')",
|
||||
buffer - buffer_start);
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
if (__isalpha (LA (1)) || LA (1) == '_' || LA (1) == '$')
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit character after got character",
|
||||
buffer - buffer_start);
|
||||
}
|
||||
is_fp = true;
|
||||
consume_char ();
|
||||
@@ -878,7 +697,8 @@ parse_number (void)
|
||||
}
|
||||
if (!__isdigit (LA (1)))
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit character after exponential marker ('e' or 'E')",
|
||||
buffer - buffer_start);
|
||||
}
|
||||
is_exp = true;
|
||||
consume_char ();
|
||||
@@ -887,7 +707,7 @@ parse_number (void)
|
||||
|
||||
if (__isalpha (c) || c == '_' || c == '$')
|
||||
{
|
||||
parser_fatal (ERR_INT_LITERAL);
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit characters", buffer - buffer_start);
|
||||
}
|
||||
|
||||
if (!__isdigit (c))
|
||||
@@ -901,10 +721,9 @@ parse_number (void)
|
||||
if (is_fp || is_exp)
|
||||
{
|
||||
ecma_number_t res = __strtof (token_start, NULL);
|
||||
token_start = NULL;
|
||||
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
@@ -914,18 +733,15 @@ parse_number (void)
|
||||
res = res * 10 + hex_to_int (token_start[i]);
|
||||
}
|
||||
|
||||
token_start = NULL;
|
||||
|
||||
if (res <= 255)
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_SMALL_INT,
|
||||
.uid = (uint8_t) res
|
||||
};
|
||||
known_token = create_token_from_current_token (TOK_SMALL_INT, (uint8_t) res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
known_token = convert_seen_num_to_token ((ecma_number_t) res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
@@ -949,18 +765,18 @@ parse_string (void)
|
||||
c = LA (0);
|
||||
if (c == '\0')
|
||||
{
|
||||
parser_fatal (ERR_UNCLOSED);
|
||||
PARSE_ERROR ("Unclosed string", token_start - buffer_start);
|
||||
}
|
||||
if (c == '\n')
|
||||
{
|
||||
parser_fatal (ERR_STRING);
|
||||
PARSE_ERROR ("String literal shall not contain newline character", token_start - buffer_start);
|
||||
}
|
||||
if (c == '\\')
|
||||
{
|
||||
/* Only single escape character is allowed. */
|
||||
if (LA (1) == 'x' || LA (1) == 'u' || __isdigit (LA (1)))
|
||||
{
|
||||
parser_fatal (ERR_STRING);
|
||||
PARSE_SORRY ("Escape sequences are not supported yet", token_start - buffer_start);
|
||||
}
|
||||
if ((LA (1) == '\'' && !is_double_quoted)
|
||||
|| (LA (1) == '"' && is_double_quoted)
|
||||
@@ -980,9 +796,9 @@ parse_string (void)
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
// Eat up '"'
|
||||
result = convert_current_token_to_token (TOK_STRING);
|
||||
|
||||
// Eat up '"'
|
||||
consume_char ();
|
||||
token_start = NULL;
|
||||
|
||||
@@ -1058,7 +874,7 @@ replace_comment_by_newline (void)
|
||||
}
|
||||
if (multiline && c == '\0')
|
||||
{
|
||||
parser_fatal (ERR_UNCLOSED);
|
||||
PARSE_ERROR ("Unclosed multiline comment", buffer - buffer_start);
|
||||
}
|
||||
consume_char ();
|
||||
}
|
||||
@@ -1091,20 +907,12 @@ lexer_next_token_private (void)
|
||||
if (c == '\n')
|
||||
{
|
||||
consume_char ();
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NEWLINE,
|
||||
.uid = 0
|
||||
};
|
||||
return create_token_from_buffer_state (TOK_NEWLINE, 0);
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
{
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_EOF,
|
||||
.uid = 0
|
||||
};
|
||||
return create_token_from_buffer_state (TOK_EOF, 0);
|
||||
}
|
||||
|
||||
if (c == '\'' || c == '"')
|
||||
@@ -1218,31 +1026,27 @@ lexer_next_token_private (void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: JERRY_UNREACHABLE ();
|
||||
default: PARSE_SORRY ("Unknown character", buffer - buffer_start);
|
||||
}
|
||||
parser_fatal (ERR_NON_CHAR);
|
||||
PARSE_SORRY ("Unknown character", buffer - buffer_start);
|
||||
}
|
||||
|
||||
token
|
||||
lexer_next_token (void)
|
||||
{
|
||||
#ifdef __TARGET_HOST_x64
|
||||
if (buffer == buffer_start)
|
||||
{
|
||||
dump_current_line ();
|
||||
}
|
||||
#endif /* __TARGET_HOST_x64 */
|
||||
|
||||
prev_token = sent_token;
|
||||
sent_token = lexer_next_token_private ();
|
||||
|
||||
#ifdef __TARGET_HOST_x64
|
||||
if (sent_token.type == TOK_NEWLINE)
|
||||
{
|
||||
dump_current_line ();
|
||||
return sent_token;
|
||||
}
|
||||
#endif /* __TARGET_HOST_x64 */
|
||||
return sent_token;
|
||||
}
|
||||
|
||||
@@ -1258,12 +1062,6 @@ lexer_prev_token (void)
|
||||
return prev_token;
|
||||
}
|
||||
|
||||
void
|
||||
lexer_dump_buffer_state (void)
|
||||
{
|
||||
__printf ("%s\n", buffer);
|
||||
}
|
||||
|
||||
void
|
||||
lexer_run_first_pass (void)
|
||||
{
|
||||
@@ -1276,6 +1074,172 @@ lexer_run_first_pass (void)
|
||||
lexer_rewind ();
|
||||
}
|
||||
|
||||
void
|
||||
lexer_locus_to_line_and_column (size_t locus, size_t *line, size_t *column)
|
||||
{
|
||||
JERRY_ASSERT (locus < buffer_size);
|
||||
const char *buf;
|
||||
size_t l = 0, c = 0;
|
||||
for (buf = buffer_start; (size_t) (buf - buffer_start) < locus; buf++)
|
||||
{
|
||||
if (*buf == '\n')
|
||||
{
|
||||
c = 0;
|
||||
l++;
|
||||
continue;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
if (line)
|
||||
{
|
||||
*line = l;
|
||||
}
|
||||
if (column)
|
||||
{
|
||||
*column = c;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lexer_dump_line (size_t line)
|
||||
{
|
||||
size_t l = 0;
|
||||
for (const char *buf = buffer_start; *buf != '\0'; buf++)
|
||||
{
|
||||
if (l == line)
|
||||
{
|
||||
for (; *buf != '\n' && *buf != '\0'; buf++)
|
||||
{
|
||||
__putchar (*buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (*buf == '\n')
|
||||
{
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
lexer_keyword_to_string (keyword kw)
|
||||
{
|
||||
switch (kw)
|
||||
{
|
||||
case KW_BREAK: return "break";
|
||||
case KW_CASE: return "case";
|
||||
case KW_CATCH: return "catch";
|
||||
|
||||
case KW_CONTINUE: return "continue";
|
||||
case KW_DEBUGGER: return "debugger";
|
||||
case KW_DEFAULT: return "default";
|
||||
case KW_DELETE: return "delete";
|
||||
case KW_DO: return "do";
|
||||
|
||||
case KW_ELSE: return "else";
|
||||
case KW_FINALLY: return "finally";
|
||||
case KW_FOR: return "for";
|
||||
case KW_FUNCTION: return "function";
|
||||
case KW_IF: return "if";
|
||||
|
||||
case KW_IN: return "in";
|
||||
case KW_INSTANCEOF: return "instanceof";
|
||||
case KW_NEW: return "new";
|
||||
case KW_RETURN: return "return";
|
||||
case KW_SWITCH: return "switch";
|
||||
|
||||
case KW_THIS: return "this";
|
||||
case KW_THROW: return "throw";
|
||||
case KW_TRY: return "try";
|
||||
case KW_TYPEOF: return "typeof";
|
||||
case KW_VAR: return "var";
|
||||
|
||||
case KW_VOID: return "void";
|
||||
case KW_WHILE: return "while";
|
||||
case KW_WITH: return "with";
|
||||
default: JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
lexer_token_type_to_string (token_type tt)
|
||||
{
|
||||
switch (tt)
|
||||
{
|
||||
case TOK_EOF: return "End of file";
|
||||
case TOK_NAME: return "Identifier";
|
||||
case TOK_KEYWORD: return "Keyword";
|
||||
case TOK_SMALL_INT: /* FALLTHRU */
|
||||
case TOK_NUMBER: return "Number";
|
||||
|
||||
case TOK_NULL: return "null";
|
||||
case TOK_BOOL: return "bool";
|
||||
case TOK_NEWLINE: return "newline";
|
||||
case TOK_STRING: return "string";
|
||||
case TOK_OPEN_BRACE: return "{";
|
||||
|
||||
case TOK_CLOSE_BRACE: return "}";
|
||||
case TOK_OPEN_PAREN: return "(";
|
||||
case TOK_CLOSE_PAREN: return ")";
|
||||
case TOK_OPEN_SQUARE: return "[";
|
||||
case TOK_CLOSE_SQUARE: return "]";
|
||||
|
||||
case TOK_DOT: return ".";
|
||||
case TOK_SEMICOLON: return ";";
|
||||
case TOK_COMMA: return ",";
|
||||
case TOK_LESS: return "<";
|
||||
case TOK_GREATER: return ">";
|
||||
|
||||
case TOK_LESS_EQ: return "<=";
|
||||
case TOK_GREATER_EQ: return "<=";
|
||||
case TOK_DOUBLE_EQ: return "==";
|
||||
case TOK_NOT_EQ: return "!=";
|
||||
case TOK_TRIPLE_EQ: return "===";
|
||||
|
||||
case TOK_NOT_DOUBLE_EQ: return "!==";
|
||||
case TOK_PLUS: return "+";
|
||||
case TOK_MINUS: return "-";
|
||||
case TOK_MULT: return "*";
|
||||
case TOK_MOD: return "%%";
|
||||
|
||||
case TOK_DOUBLE_PLUS: return "++";
|
||||
case TOK_DOUBLE_MINUS: return "--";
|
||||
case TOK_LSHIFT: return "<<";
|
||||
case TOK_RSHIFT: return ">>";
|
||||
case TOK_RSHIFT_EX: return ">>>";
|
||||
|
||||
case TOK_AND: return "&";
|
||||
case TOK_OR: return "|";
|
||||
case TOK_XOR: return "^";
|
||||
case TOK_NOT: return "!";
|
||||
case TOK_COMPL: return "~";
|
||||
|
||||
case TOK_DOUBLE_AND: return "&&";
|
||||
case TOK_DOUBLE_OR: return "||";
|
||||
case TOK_QUERY: return "?";
|
||||
case TOK_COLON: return ":";
|
||||
case TOK_EQ: return "=";
|
||||
|
||||
case TOK_PLUS_EQ: return "+=";
|
||||
case TOK_MINUS_EQ: return "-=";
|
||||
case TOK_MULT_EQ: return "*=";
|
||||
case TOK_MOD_EQ: return "%%=";
|
||||
case TOK_LSHIFT_EQ: return "<<=";
|
||||
|
||||
case TOK_RSHIFT_EQ: return ">>=";
|
||||
case TOK_RSHIFT_EX_EQ: return ">>>=";
|
||||
case TOK_AND_EQ: return "&=";
|
||||
case TOK_OR_EQ: return "|=";
|
||||
case TOK_XOR_EQ: return "^=";
|
||||
|
||||
case TOK_DIV: return "/";
|
||||
case TOK_DIV_EQ: return "/=";
|
||||
case TOK_UNDEFINED: return "undefined";
|
||||
default: JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lexer_init (const char *source, size_t source_size, bool show_opcodes)
|
||||
{
|
||||
|
||||
@@ -139,8 +139,8 @@ typedef uint8_t token_type;
|
||||
typedef struct
|
||||
{
|
||||
token_type type;
|
||||
|
||||
uint8_t uid;
|
||||
size_t locus;
|
||||
}
|
||||
__packed
|
||||
token;
|
||||
@@ -154,8 +154,6 @@ token lexer_next_token (void);
|
||||
void lexer_save_token (token);
|
||||
token lexer_prev_token (void);
|
||||
|
||||
void lexer_dump_buffer_state (void);
|
||||
|
||||
uint8_t lexer_get_reserved_ids_count (void);
|
||||
|
||||
const lp_string *lexer_get_strings (void);
|
||||
@@ -168,4 +166,9 @@ uint8_t lexer_get_nums_count (void);
|
||||
|
||||
void lexer_adjust_num_ids (void);
|
||||
|
||||
void lexer_locus_to_line_and_column (size_t, size_t *, size_t *);
|
||||
void lexer_dump_line (size_t);
|
||||
const char *lexer_keyword_to_string (keyword);
|
||||
const char *lexer_token_type_to_string (token_type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PARSE_ERROR_H
|
||||
#define PARSE_ERROR_H
|
||||
|
||||
#define PARSE_ERROR(MESSAGE, LOCUS) do { \
|
||||
size_t line, column; \
|
||||
lexer_locus_to_line_and_column ((size_t) (LOCUS), &line, &column); \
|
||||
lexer_dump_line (line); \
|
||||
__printf ("\n"); \
|
||||
for (size_t i = 0; i < column; i++) { \
|
||||
__putchar (' '); \
|
||||
} \
|
||||
__printf ("^\n"); \
|
||||
__printf ("ERROR: Ln %d, Col %d: %s\n", line + 1, column + 1, MESSAGE); \
|
||||
__exit (-1); \
|
||||
} while (0)
|
||||
#define PARSE_ERROR_VARG(MESSAGE, LOCUS, ...) do { \
|
||||
size_t line, column; \
|
||||
lexer_locus_to_line_and_column ((size_t) (LOCUS), &line, &column); \
|
||||
lexer_dump_line (line); \
|
||||
__printf ("\n"); \
|
||||
for (size_t i = 0; i < column; i++) { \
|
||||
__putchar (' '); \
|
||||
} \
|
||||
__printf ("\n^\n"); \
|
||||
__printf ("ERROR: Ln %d, Col %d: ", line + 1, column + 1); \
|
||||
__printf (MESSAGE, __VA_ARGS__); \
|
||||
__printf ("\n"); \
|
||||
__exit (-1); \
|
||||
} while (0)
|
||||
#define PARSE_SORRY(MESSAGE, LOCUS) do { \
|
||||
size_t line, column; \
|
||||
lexer_locus_to_line_and_column ((size_t) (LOCUS), &line, &column); \
|
||||
lexer_dump_line (line); \
|
||||
__printf ("\n"); \
|
||||
for (size_t i = 0; i < column; i++) { \
|
||||
__putchar (' '); \
|
||||
} \
|
||||
__printf ("^\n"); \
|
||||
__printf ("SORRY, Unimplemented: Ln %d, Col %d: %s\n", line + 1, column + 1, MESSAGE); \
|
||||
__exit (-1); \
|
||||
} while (0)
|
||||
|
||||
#endif /* PARSE_ERROR_H */
|
||||
+36
-35
@@ -24,6 +24,7 @@
|
||||
#include "hash-table.h"
|
||||
#include "deserializer.h"
|
||||
#include "opcodes-native-call.h"
|
||||
#include "parse-error.h"
|
||||
|
||||
#define INVALID_VALUE 255
|
||||
#define INTRINSICS_COUNT 1
|
||||
@@ -266,6 +267,17 @@ do { \
|
||||
STACK_CHECK_USAGE (IDX); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_ERROR(MESSAGE) PARSE_ERROR(MESSAGE, TOK().locus)
|
||||
#define EMIT_SORRY(MESSAGE) PARSE_SORRY(MESSAGE, TOK().locus)
|
||||
#define EMIT_ERROR_VARG(MESSAGE, ...) PARSE_ERROR_VARG(MESSAGE, TOK().locus, __VA_ARGS__)
|
||||
|
||||
#define NESTING_TO_STRING(I) (I == NESTING_FUNCTION \
|
||||
? "function" \
|
||||
: I == NESTING_ITERATIONAL \
|
||||
? "iterational" \
|
||||
: I == NESTING_SWITCH \
|
||||
? "switch" : "unknown")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AL_FUNC_DECL,
|
||||
@@ -348,7 +360,7 @@ must_be_inside_but_not_in (uint8_t *inside, uint8_t insides_count, uint8_t not_i
|
||||
|
||||
if (STACK_SIZE(nestings) == 0)
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Shall be inside a nesting");
|
||||
}
|
||||
|
||||
SET_I(STACK_SIZE(nestings));
|
||||
@@ -356,7 +368,7 @@ must_be_inside_but_not_in (uint8_t *inside, uint8_t insides_count, uint8_t not_i
|
||||
{
|
||||
if (STACK_ELEMENT (nestings, I() - 1) == not_in)
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR_VARG ("Shall not be inside a '%s' nesting", NESTING_TO_STRING(not_in));
|
||||
}
|
||||
|
||||
SET_J(0);
|
||||
@@ -371,7 +383,13 @@ must_be_inside_but_not_in (uint8_t *inside, uint8_t insides_count, uint8_t not_i
|
||||
SET_I(I()-1);
|
||||
}
|
||||
|
||||
parser_fatal (ERR_PARSER);
|
||||
switch (insides_count)
|
||||
{
|
||||
case 1: EMIT_ERROR_VARG ("Shall be inside a '%s' nesting", NESTING_TO_STRING(inside[0])); break;
|
||||
case 2: EMIT_ERROR_VARG ("Shall be inside '%s' or '%s' nestings",
|
||||
NESTING_TO_STRING(inside[0]), NESTING_TO_STRING(inside[1])); break;
|
||||
default: JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
STACK_DROP (U8, 2);
|
||||
@@ -405,9 +423,7 @@ assert_keyword (keyword kw)
|
||||
{
|
||||
if (!token_is (TOK_KEYWORD) || token_data () != kw)
|
||||
{
|
||||
#ifdef __TARGET_HOST_x64
|
||||
__printf ("assert_keyword: %d\n", kw);
|
||||
#endif
|
||||
EMIT_ERROR_VARG ("Expected keyword '%s'", lexer_keyword_to_string (kw));
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
@@ -423,10 +439,7 @@ current_token_must_be (token_type tt)
|
||||
{
|
||||
if (!token_is (tt))
|
||||
{
|
||||
#ifdef __TARGET_HOST_x64
|
||||
__printf ("current_token_must_be: %d\n", tt);
|
||||
#endif
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR_VARG ("Expected '%s' token", lexer_token_type_to_string (tt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,10 +459,7 @@ next_token_must_be (token_type tt)
|
||||
skip_token ();
|
||||
if (!token_is (tt))
|
||||
{
|
||||
#ifdef __TARGET_HOST_x64
|
||||
__printf ("next_token_must_be: %d\n", tt);
|
||||
#endif
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR_VARG ("Expected '%s' token", lexer_token_type_to_string (tt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +469,7 @@ token_after_newlines_must_be (token_type tt)
|
||||
skip_newlines ();
|
||||
if (!token_is (tt))
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR_VARG ("Expected '%s' token", lexer_token_type_to_string (tt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +479,7 @@ token_after_newlines_must_be_keyword (keyword kw)
|
||||
skip_newlines ();
|
||||
if (!is_keyword (kw))
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR_VARG ("Expected keyword '%s'", lexer_keyword_to_string (kw));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1348,7 +1358,7 @@ parse_member_expression (idx_t *this_arg)
|
||||
skip_newlines ();
|
||||
if (!token_is (TOK_NAME))
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Expected identifier");
|
||||
}
|
||||
STACK_PUSH (IDX, next_temp_name ());
|
||||
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
|
||||
@@ -1579,11 +1589,11 @@ parse_unary_expression (void)
|
||||
lhs = delete_prop for 'delete expr[expr]';
|
||||
lhs = true - otherwise; */);
|
||||
// DUMP_OPCODE_2 (delete, lhs, expr);
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
EMIT_SORRY ("Operation 'delete' is not supported yet");
|
||||
}
|
||||
if (is_keyword (KW_VOID))
|
||||
{
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
EMIT_SORRY ("Operation 'void' is not supported yet");
|
||||
}
|
||||
if (is_keyword (KW_TYPEOF))
|
||||
{
|
||||
@@ -2331,7 +2341,7 @@ parse_for_or_for_in_statement (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Expected either ':' or 'in' token");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2351,7 +2361,7 @@ parse_for_or_for_in_statement (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Expected either ':' or 'in' token");
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
@@ -2430,7 +2440,7 @@ plain_for:
|
||||
goto cleanup;
|
||||
|
||||
for_in:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
EMIT_SORRY ("'for in' loops are not supported yet");
|
||||
|
||||
cleanup:
|
||||
STACK_CHECK_USAGE (IDX);
|
||||
@@ -2644,7 +2654,7 @@ parse_with_statement (void)
|
||||
static void
|
||||
parse_switch_statement (void)
|
||||
{
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
EMIT_SORRY ("'switch' is not supported yet");
|
||||
}
|
||||
|
||||
/* catch_clause
|
||||
@@ -2751,7 +2761,7 @@ parse_try_statement (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Expected either 'catch' or 'finally' token");
|
||||
}
|
||||
|
||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_END_TRY_CATCH_FINALLY, INVALID_VALUE, INVALID_VALUE);
|
||||
@@ -2772,7 +2782,7 @@ insert_semicolon (void)
|
||||
}
|
||||
if (!token_is (TOK_SEMICOLON))
|
||||
{
|
||||
parser_fatal (ERR_PARSER);
|
||||
EMIT_ERROR ("Expected either ';' or newline token");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2962,7 +2972,7 @@ parse_statement (void)
|
||||
if (token_is (TOK_COLON))
|
||||
{
|
||||
// STMT_LABELLED;
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
EMIT_SORRY ("Labelled statements are not supported yet");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3145,12 +3155,3 @@ parser_free (void)
|
||||
serializer_free ();
|
||||
lexer_free ();
|
||||
}
|
||||
|
||||
void
|
||||
parser_fatal (jerry_status_t code)
|
||||
{
|
||||
__printf ("FATAL: %d\n", code);
|
||||
lexer_dump_buffer_state ();
|
||||
|
||||
jerry_exit (code);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,4 @@ void parser_init (const char *, size_t, bool);
|
||||
void parser_parse_program (void);
|
||||
void parser_free (void);
|
||||
|
||||
void parser_fatal (jerry_status_t code);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
void __noreturn
|
||||
jerry_assert_fail (const char *assertion, /**< assertion condition string */
|
||||
const char *file, /**< file name */
|
||||
const char *function, /**< function name */
|
||||
const uint32_t line) /** line */
|
||||
{
|
||||
__printf ("Assertion '%s' failed at %s:%u.\n",
|
||||
assertion, file, line);
|
||||
__printf ("ICE: Assertion '%s' failed at %s(%s):%u.\n",
|
||||
assertion, file, function, line);
|
||||
|
||||
__exit (-ERR_FAILED_INTERNAL_ASSERTION);
|
||||
} /* jerry_assert_fail */
|
||||
@@ -37,9 +38,10 @@ void __noreturn
|
||||
jerry_unreachable (const char *comment, /**< comment to unreachable mark if exists,
|
||||
NULL - otherwise */
|
||||
const char *file, /**< file name */
|
||||
const char *function, /**< function name */
|
||||
const uint32_t line) /**< line */
|
||||
{
|
||||
__printf ("Unreachable control path at %s:%u was executed", file, line);
|
||||
__printf ("ICE: Unreachable control path at %s(%s):%u was executed", file, function, line);
|
||||
if (comment != NULL)
|
||||
{
|
||||
__printf ("(%s)", comment);
|
||||
@@ -56,9 +58,10 @@ void __noreturn
|
||||
jerry_unimplemented (const char *comment, /**< comment to unimplemented mark if exists,
|
||||
NULL - otherwise */
|
||||
const char *file, /**< file name */
|
||||
const char *function, /**< function name */
|
||||
const uint32_t line) /**< line */
|
||||
{
|
||||
__printf ("Unimplemented case at %s:%u was executed", file, line);
|
||||
__printf ("SORRY: Unimplemented case at %s(%s):%u was executed", file, function, line);
|
||||
if (comment != NULL)
|
||||
{
|
||||
__printf ("(%s)", comment);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
void __noreturn
|
||||
jerry_assert_fail (const char *assertion __unused, /**< assertion condition string */
|
||||
const char *file __unused, /**< file name */
|
||||
const char *function __unused, /**< function name */
|
||||
const uint32_t line __unused) /** line */
|
||||
{
|
||||
__exit (-ERR_FAILED_INTERNAL_ASSERTION);
|
||||
@@ -34,6 +35,7 @@ void __noreturn
|
||||
jerry_unreachable (const char *comment __unused, /**< comment to unreachable mark if exists,
|
||||
NULL - otherwise */
|
||||
const char *file __unused, /**< file name */
|
||||
const char *function __unused, /**< function name */
|
||||
const uint32_t line __unused) /**< line */
|
||||
{
|
||||
__exit (-ERR_FAILED_INTERNAL_ASSERTION);
|
||||
@@ -46,6 +48,7 @@ void __noreturn
|
||||
jerry_unimplemented (const char *comment __unused, /**< comment to unimplemented mark if exists,
|
||||
NULL - otherwise */
|
||||
const char *file __unused, /**< file name */
|
||||
const char *function __unused, /**< function name */
|
||||
const uint32_t line __unused) /**< line */
|
||||
{
|
||||
__exit (-ERR_UNIMPLEMENTED_CASE);
|
||||
|
||||
Reference in New Issue
Block a user