Merge line-by-line parser

This commit is contained in:
Ilmir Usmanov
2014-07-09 16:17:42 +04:00
parent 823432664e
commit f46d5b440c
24 changed files with 2416 additions and 3404 deletions
+2
View File
@@ -20,3 +20,5 @@ nbproject
# Random Trash # Random Trash
*~ *~
js.files
core
+2 -2
View File
@@ -83,8 +83,8 @@ CFLAGS ?= $(INCLUDES) -std=c99 -m32 #-fdiagnostics-color=always
#CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard #CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
#CFLAGS += -ffunction-sections -fdata-sections #CFLAGS += -ffunction-sections -fdata-sections
DEBUG_OPTIONS = -g3 -O0 -DDEBUG# -fsanitize=address DEBUG_OPTIONS = -g3 -O0 -DJERRY_NDEBUG# -fsanitize=address
RELEASE_OPTIONS = -Os -Werror -DNDEBUG RELEASE_OPTIONS = -Os -Werror -DJERRY_NDEBUG
DEFINES = -DMEM_HEAP_CHUNK_SIZE=256 -DMEM_HEAP_AREA_SIZE=32768 DEFINES = -DMEM_HEAP_CHUNK_SIZE=256 -DMEM_HEAP_AREA_SIZE=32768
TARGET_HOST = -D__HOST TARGET_HOST = -D__HOST
+3 -7
View File
@@ -16,20 +16,16 @@
#ifndef ERROR_H #ifndef ERROR_H
#define ERROR_H #define ERROR_H
#include <assert.h> #include "mappings.h"
#include <stdio.h>
#include <stdlib.h>
void lexer_dump_buffer_state (); extern void lexer_dump_buffer_state ();
#define unreachable() assert(0)
static inline void static inline void
fatal (int code) fatal (int code)
{ {
printf ("FATAL: %d\n", code); printf ("FATAL: %d\n", code);
lexer_dump_buffer_state (); lexer_dump_buffer_state ();
unreachable (); JERRY_UNREACHABLE ();
exit (code); exit (code);
} }
+1 -1
View File
@@ -73,7 +73,7 @@ extern uint32_t jerry_UnreferencedExpression;
/** /**
* Mark for unreachable points and unimplemented cases * Mark for unreachable points and unimplemented cases
*/ */
#define JERRY_UNREACHABLE() { JERRY_ASSERT( false); __builtin_trap(); } #define JERRY_UNREACHABLE() do { JERRY_ASSERT( false); __builtin_trap(); } while (0)
#define JERRY_UNIMPLEMENTED() JERRY_UNREACHABLE() #define JERRY_UNIMPLEMENTED() JERRY_UNREACHABLE()
/** /**
+174 -9
View File
@@ -29,7 +29,7 @@ extern int vprintf (__const char *__restrict __format, __builtin_va_list __arg);
* @return @s * @return @s
*/ */
void* void*
libc_memset(void *s, /**< area to set values in */ __memset(void *s, /**< area to set values in */
int c, /**< value to set */ int c, /**< value to set */
size_t n) /**< area size */ size_t n) /**< area size */
{ {
@@ -40,7 +40,7 @@ libc_memset(void *s, /**< area to set values in */
} }
return s; return s;
} /* libc_memset */ } /* __memset */
/** /**
* memcmp * memcmp
@@ -50,7 +50,7 @@ libc_memset(void *s, /**< area to set values in */
* 1, otherwise * 1, otherwise
*/ */
int int
libc_memcmp(const void *s1, /**< first area */ __memcmp(const void *s1, /**< first area */
const void *s2, /**< second area */ const void *s2, /**< second area */
size_t n) /**< area size */ size_t n) /**< area size */
{ {
@@ -67,13 +67,13 @@ libc_memcmp(const void *s1, /**< first area */
} }
return 0; return 0;
} /* libc_memcmp */ } /* __memcmp */
/** /**
* memcpy * memcpy
*/ */
void void *
libc_memcpy(void *s1, /**< destination */ __memcpy(void *s1, /**< destination */
const void *s2, /**< source */ const void *s2, /**< source */
size_t n) /**< bytes number */ size_t n) /**< bytes number */
{ {
@@ -84,7 +84,9 @@ libc_memcpy(void *s1, /**< destination */
{ {
pArea1[ index ] = pArea2[ index ]; pArea1[ index ] = pArea2[ index ];
} }
} /* libc_memcpy */
return s1;
} /* __memcpy */
/** /**
* printf * printf
@@ -92,7 +94,7 @@ libc_memcpy(void *s1, /**< destination */
* @return number of characters printed * @return number of characters printed
*/ */
int int
libc_printf(const char *format, /**< format string */ __printf(const char *format, /**< format string */
...) /**< parameters' values */ ...) /**< parameters' values */
{ {
va_list args; va_list args;
@@ -104,4 +106,167 @@ libc_printf(const char *format, /**< format string */
va_end( args); va_end( args);
return ret; return ret;
} /* libc_printf */ } /* __printf */
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
return __printf ("%c", c);
}
/** exit - cause normal process termination. Infinite loop. */
void
__exit (int status __unused)
{
for (;;)
;
}
/** Compare two strings. return an integer less than, equal to, or greater than zero
if s1 is found, respectively, to be less than, to match, or be greater than s2. */
int
__strcmp (const char *s1, const char *s2)
{
size_t i;
if (s1 == NULL)
{
if (s2 != NULL)
return -1;
else
return 0;
}
if (s2 == NULL)
return 1;
for (i = 0; s1[i]; i++)
{
if (s1[i] > s2[i])
return 1;
else if (s1[i] < s2[i])
return -1;
}
if (s2[i])
return -1;
return 0;
}
/** Compare two strings. return an integer less than, equal to, or greater than zero
if the first n character of s1 is found, respectively, to be less than, to match,
or be greater than the first n character of s2. */
int
__strncmp (const char *s1, const char *s2, size_t n)
{
size_t i;
if (s1 == NULL)
{
if (s2 != NULL)
return -1;
else
return 0;
}
if (s2 == NULL)
return 1;
for (i = 0; i < n; i++)
{
if (s1[i] > s2[i])
return 1;
else if (s1[i] < s2[i])
return -1;
}
return 0;
}
/** Copy a string. At most n bytes of src are copied. Warning: If there is no
null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
@return a pointer to the destination string dest. */
char *
__strncpy(char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
dest[i] = src[i];
return dest;
}
/** Convert the initial portion of the string pointed to by nptr to float representation. */
float
__strtof (const char *nptr, char **endptr)
{
(void) nptr;
(void) endptr;
JERRY_UNIMPLEMENTED ();
}
/** Calculate the length of a string. */
size_t
__strlen (const char *s)
{
size_t i;
for (i = 0; s[i]; i++)
;
return i;
}
/** Checks for white-space characters. In the "C" and "POSIX" locales, these are: space,
form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). */
int
__isspace (int c)
{
switch (c)
{
case ' ':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
return 1;
default:
return 0;
}
}
/** Checks for an uppercase letter. */
int
__isupper (int c)
{
return c >= 'A' && c <= 'Z';
}
/** Checks for an lowercase letter. */
int
__islower (int c)
{
return c >= 'a' && c <= 'z';
}
/** Checks for an alphabetic character.
In the standard "C" locale, it is equivalent to (isupper(c) || islower(c)). */
int
__isalpha (int c)
{
return __isupper (c) || __islower (c);
}
/** Checks for a digit (0 through 9). */
int
__isdigit (int c)
{
return c >= '0' && c <= '9';
}
/** checks for a hexadecimal digits, that is, one of
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F. */
int
__isxdigit (int c)
{
return __isdigit (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
+25 -4
View File
@@ -21,9 +21,30 @@
#include "globals.h" #include "globals.h"
extern void *libc_memset(void *s, int c, size_t n); extern void *__memset (void *s, int c, size_t n);
extern int libc_memcmp(const void *s1, const void *s2, size_t n); extern int __memcmp (const void *s1, const void *s2, size_t n);
extern void libc_memcpy(void *s1, const void *s2, size_t n); extern void *__memcpy (void *s1, const void *s2, size_t n);
extern int libc_printf(const char *format, ...); extern int __printf (const char *format, ...);
extern int __putchar (int);
extern void __exit (int);
extern int __strcmp (const char *, const char *);
extern int __strncmp (const char *, const char *, size_t);
extern char *__strncpy (char *, const char *, size_t);
extern float __strtof (const char *, char **);
extern size_t __strlen (const char *);
extern int __isspace (int);
extern int __isupper (int);
extern int __islower (int);
extern int __isalpha (int);
extern int __isdigit (int);
extern int __isxdigit (int);
#define DBL_MANT_DIG ( 52)
#define DBL_DIG ( 10)
#define DBL_MIN_EXP (-324)
#define DBL_MAX_EXP ( 308)
#define HUGE_VAL (1e37)
#endif /* JERRY_LIBC_H */ #endif /* JERRY_LIBC_H */
+5 -5
View File
@@ -346,7 +346,7 @@ mem_HeapPrint( bool dumpBlockData) /**< print block with data (true)
{ {
mem_CheckHeap(); mem_CheckHeap();
libc_printf("Heap: start=%p size=%lu, first block->%p, last block->%p\n", __printf("Heap: start=%p size=%lu, first block->%p, last block->%p\n",
mem_Heap.m_HeapStart, mem_Heap.m_HeapStart,
mem_Heap.m_HeapSize, mem_Heap.m_HeapSize,
(void*) mem_Heap.m_pFirstBlock, (void*) mem_Heap.m_pFirstBlock,
@@ -356,7 +356,7 @@ mem_HeapPrint( bool dumpBlockData) /**< print block with data (true)
pBlock != NULL; pBlock != NULL;
pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] )
{ {
libc_printf("Block (%p): magic num=0x%08x, size in chunks=%lu, previous block->%p next block->%p\n", __printf("Block (%p): magic num=0x%08x, size in chunks=%lu, previous block->%p next block->%p\n",
(void*) pBlock, (void*) pBlock,
pBlock->m_MagicNum, pBlock->m_MagicNum,
pBlock->m_SizeInChunks, pBlock->m_SizeInChunks,
@@ -370,13 +370,13 @@ mem_HeapPrint( bool dumpBlockData) /**< print block with data (true)
offset < mem_GetHeapBlockDataSpaceSizeInBytes( pBlock); offset < mem_GetHeapBlockDataSpaceSizeInBytes( pBlock);
offset++ ) offset++ )
{ {
libc_printf("%02x ", pBlockData[ offset ]); __printf("%02x ", pBlockData[ offset ]);
} }
libc_printf("\n"); __printf("\n");
} }
} }
libc_printf("\n"); __printf("\n");
} /* mem_PrintHeap */ } /* mem_PrintHeap */
/** /**
+5 -5
View File
@@ -111,10 +111,10 @@ mem_PoolInit(mem_PoolState_t *pPool, /**< pool */
* All chunks are free right after initialization * All chunks are free right after initialization
*/ */
pPool->m_FreeChunksNumber = chunksNumber; pPool->m_FreeChunksNumber = chunksNumber;
libc_memset( pPool->m_pBitmap, 0, bitmapAreaSize); __memset( pPool->m_pBitmap, 0, bitmapAreaSize);
#ifndef JERRY_NDEBUG #ifndef JERRY_NDEBUG
libc_memset( pPool->m_pChunks, mem_PoolFreeChunkMagicNum, chunksAreaSize); __memset( pPool->m_pChunks, mem_PoolFreeChunkMagicNum, chunksAreaSize);
#endif /* JERRY_NDEBUG */ #endif /* JERRY_NDEBUG */
mem_CheckPool( pPool); mem_CheckPool( pPool);
@@ -198,7 +198,7 @@ mem_PoolFreeChunk(mem_PoolState_t *pPool, /**< pool */
mword_t bitMask = ( 1lu << bitmapBitInBlock ); mword_t bitMask = ( 1lu << bitmapBitInBlock );
#ifndef JERRY_NDEBUG #ifndef JERRY_NDEBUG
libc_memset( (uint8_t*) pChunk, mem_PoolFreeChunkMagicNum, pPool->m_ChunkSize); __memset( (uint8_t*) pChunk, mem_PoolFreeChunkMagicNum, pPool->m_ChunkSize);
#endif /* JERRY_NDEBUG */ #endif /* JERRY_NDEBUG */
JERRY_ASSERT( pPool->m_pBitmap[ bitmapBlockIndex ] & bitMask ); JERRY_ASSERT( pPool->m_pBitmap[ bitmapBlockIndex ] & bitMask );
@@ -221,7 +221,7 @@ mem_CheckPool( mem_PoolState_t __unused *pPool) /**< pool (unused #ifdef JERRY_N
JERRY_ASSERT( (uint8_t*) pPool->m_pChunks > pPool->m_pPoolStart ); JERRY_ASSERT( (uint8_t*) pPool->m_pChunks > pPool->m_pPoolStart );
uint8_t freeChunkTemplate[ pPool->m_ChunkSize ]; uint8_t freeChunkTemplate[ pPool->m_ChunkSize ];
libc_memset( &freeChunkTemplate, mem_PoolFreeChunkMagicNum, sizeof (freeChunkTemplate)); __memset( &freeChunkTemplate, mem_PoolFreeChunkMagicNum, sizeof (freeChunkTemplate));
size_t metFreeChunksNumber = 0; size_t metFreeChunksNumber = 0;
@@ -242,7 +242,7 @@ mem_CheckPool( mem_PoolState_t __unused *pPool) /**< pool (unused #ifdef JERRY_N
{ {
metFreeChunksNumber++; metFreeChunksNumber++;
JERRY_ASSERT( libc_memcmp( &pPool->m_pChunks[ chunkIndex * pPool->m_ChunkSize ], freeChunkTemplate, pPool->m_ChunkSize) == 0 ); JERRY_ASSERT( __memcmp( &pPool->m_pChunks[ chunkIndex * pPool->m_ChunkSize ], freeChunkTemplate, pPool->m_ChunkSize) == 0 );
} }
} }
} }
+1 -1
View File
@@ -31,13 +31,13 @@ gen_bytecode ()
wait(500); wait(500);
} }
*/
save_op_data (0, getop_loop_inf (1)); save_op_data (0, getop_loop_inf (1));
save_op_data (1, getop_call_1 (0, 12)); save_op_data (1, getop_call_1 (0, 12));
save_op_data (2, getop_call_1 (0, 13)); save_op_data (2, getop_call_1 (0, 13));
save_op_data (3, getop_call_1 (0, 14)); save_op_data (3, getop_call_1 (0, 14));
save_op_data (4, getop_call_1 (0, 15)); save_op_data (4, getop_call_1 (0, 15));
save_op_data (5, getop_jmp (0)); save_op_data (5, getop_jmp (0));
*/
#ifdef __MCU #ifdef __MCU
// It's mandatory to restart app! // It's mandatory to restart app!
+1 -1
View File
@@ -16,7 +16,7 @@
#ifndef INTERPRETER_H #ifndef INTERPRETER_H
#define INTERPRETER_H #define INTERPRETER_H
#ifdef __HOST #ifdef JERRY_NDEBUG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
+54 -54
View File
@@ -23,60 +23,60 @@ save_op_data (int pos, OPCODE opdata)
__program[pos] = opdata; __program[pos] = opdata;
} }
void opfunc_loop_init_num (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_loop_init_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_loop_precond_begin_num (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_loop_precond_begin_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_loop_precond_end_num (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_loop_precond_end_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_loop_postcond (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_loop_postcond (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_call_2 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_call_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_call_n (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_call_n (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_func_decl_1 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_func_decl_1 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_func_decl_2 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_func_decl_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_func_decl_n (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_func_decl_n (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_1 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_1 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_1_end (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_1_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_2 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_2_end (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_2_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_3 (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_3 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_varg_3_end (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_varg_3_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_retval (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_retval (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_ret (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_ret (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_multiplication (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_devision (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_devision (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_remainder (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_addition (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_substruction (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_substruction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_shift_left (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_shift_left (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_shift_right (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_shift_right (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_shift_uright (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_shift_uright (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_b_and (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_b_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_b_xor (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_b_xor (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_assignment_b_or (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_assignment_b_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_logical_and (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_logical_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_logical_or (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_logical_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_and (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_or (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_xor (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_xor (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_shift_left (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_shift_left (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_shift_right (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_shift_right (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_b_shift_uright (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_b_shift_uright (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_addition (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_substraction (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_substraction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_division (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_division (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_multiplication (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_remainder (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_jmp_up (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_jmp_up (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_jmp_down (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_jmp_down (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_true_jmp (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_true_jmp (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_false_jmp (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_false_jmp (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_less_than (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_less_than (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_less_or_equal (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_less_or_equal (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_greater_than (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_greater_than (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_greater_or_equal (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_greater_or_equal (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_equal_value (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_equal_value (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_not_equal_value (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_not_equal_value (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_equal_value_type (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_equal_value_type (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void opfunc_is_not_equal_value_type (OPCODE opdata, struct __int_data *int_data) { unreachable (); } void opfunc_is_not_equal_value_type (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); }
void void
opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data) opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data)
+1 -1
View File
@@ -16,7 +16,7 @@
#ifndef OPCODES_H #ifndef OPCODES_H
#define OPCODES_H #define OPCODES_H
#ifdef __HOST #ifdef JERRY_NDEBUG
#include <stdio.h> #include <stdio.h>
#endif #endif
+2 -2
View File
@@ -167,7 +167,7 @@ ctx_Init(void)
JERRY_ASSERT( ctx_ContextsNumber == 0 ); JERRY_ASSERT( ctx_ContextsNumber == 0 );
#ifndef JERRY_NDEBUG #ifndef JERRY_NDEBUG
libc_memset( ctx_Stack, 0, sizeof (ctx_Stack)); __memset( ctx_Stack, 0, sizeof (ctx_Stack));
#endif /* !JERRY_NDEBUG */ #endif /* !JERRY_NDEBUG */
ctx_InitGlobalObject(); ctx_InitGlobalObject();
@@ -382,7 +382,7 @@ ctx_CopyVariable(ctx_SyntacticReference_t *pVarFrom, /**< source variable */
case ECMA_TYPE_NUMBER: case ECMA_TYPE_NUMBER:
{ {
ecma_Number_t *pNumberCopy = ecma_AllocNumber(); ecma_Number_t *pNumberCopy = ecma_AllocNumber();
libc_memcpy( pNumberCopy, __memcpy( pNumberCopy,
ecma_GetPointer( sourceVariableValue.m_Value), ecma_GetPointer( sourceVariableValue.m_Value),
sizeof (ecma_Number_t)); sizeof (ecma_Number_t));
ecma_SetPointer( destinationVariableValue.m_Value, pNumberCopy); ecma_SetPointer( destinationVariableValue.m_Value, pNumberCopy);
+6 -6
View File
@@ -221,7 +221,7 @@ ecma_NewEcmaString(const ecma_Char_t *pString, /**< buffer of characters */
uint8_t *copyPointer = (uint8_t*) pString; uint8_t *copyPointer = (uint8_t*) pString;
size_t charsLeft = length; size_t charsLeft = length;
size_t charsToCopy = JERRY_MIN( length, sizeof (pStringFirstChunk->m_Elements) / sizeof (ecma_Char_t)); size_t charsToCopy = JERRY_MIN( length, sizeof (pStringFirstChunk->m_Elements) / sizeof (ecma_Char_t));
libc_memcpy(pStringFirstChunk->m_Elements, copyPointer, charsToCopy * sizeof (ecma_Char_t)); __memcpy(pStringFirstChunk->m_Elements, copyPointer, charsToCopy * sizeof (ecma_Char_t));
charsLeft -= charsToCopy; charsLeft -= charsToCopy;
copyPointer += charsToCopy * sizeof (ecma_Char_t); copyPointer += charsToCopy * sizeof (ecma_Char_t);
@@ -233,7 +233,7 @@ ecma_NewEcmaString(const ecma_Char_t *pString, /**< buffer of characters */
pStringNonFirstChunk = ecma_AllocArrayNonFirstChunk(); pStringNonFirstChunk = ecma_AllocArrayNonFirstChunk();
size_t charsToCopy = JERRY_MIN( charsLeft, sizeof (pStringNonFirstChunk->m_Elements) / sizeof (ecma_Char_t)); size_t charsToCopy = JERRY_MIN( charsLeft, sizeof (pStringNonFirstChunk->m_Elements) / sizeof (ecma_Char_t));
libc_memcpy(pStringNonFirstChunk->m_Elements, copyPointer, charsToCopy * sizeof (ecma_Char_t)); __memcpy(pStringNonFirstChunk->m_Elements, copyPointer, charsToCopy * sizeof (ecma_Char_t));
charsLeft -= charsToCopy; charsLeft -= charsToCopy;
copyPointer += charsToCopy * sizeof (ecma_Char_t); copyPointer += charsToCopy * sizeof (ecma_Char_t);
@@ -274,7 +274,7 @@ ecma_CopyEcmaStringCharsToBuffer(ecma_ArrayFirstChunk_t *pFirstChunk, /**< first
uint8_t *destPointer = pBuffer + sizeof (ecma_Length_t); uint8_t *destPointer = pBuffer + sizeof (ecma_Length_t);
size_t copyChunkChars = JERRY_MIN(sizeof (pFirstChunk->m_Elements) / sizeof (ecma_Char_t), size_t copyChunkChars = JERRY_MIN(sizeof (pFirstChunk->m_Elements) / sizeof (ecma_Char_t),
charsLeft); charsLeft);
libc_memcpy( destPointer, pFirstChunk->m_Elements, copyChunkChars * sizeof (ecma_Char_t)); __memcpy( destPointer, pFirstChunk->m_Elements, copyChunkChars * sizeof (ecma_Char_t));
destPointer += copyChunkChars * sizeof (ecma_Char_t); destPointer += copyChunkChars * sizeof (ecma_Char_t);
charsLeft -= copyChunkChars; charsLeft -= copyChunkChars;
@@ -286,7 +286,7 @@ ecma_CopyEcmaStringCharsToBuffer(ecma_ArrayFirstChunk_t *pFirstChunk, /**< first
copyChunkChars = JERRY_MIN(sizeof (pNonFirstChunk->m_Elements) / sizeof (ecma_Char_t), copyChunkChars = JERRY_MIN(sizeof (pNonFirstChunk->m_Elements) / sizeof (ecma_Char_t),
charsLeft); charsLeft);
libc_memcpy( destPointer, pNonFirstChunk->m_Elements, copyChunkChars * sizeof (ecma_Char_t)); __memcpy( destPointer, pNonFirstChunk->m_Elements, copyChunkChars * sizeof (ecma_Char_t));
destPointer += copyChunkChars * sizeof (ecma_Char_t); destPointer += copyChunkChars * sizeof (ecma_Char_t);
charsLeft -= copyChunkChars; charsLeft -= copyChunkChars;
@@ -307,7 +307,7 @@ ecma_DuplicateEcmaString( ecma_ArrayFirstChunk_t *pFirstChunk) /**< first chunk
JERRY_ASSERT( pFirstChunk != NULL ); JERRY_ASSERT( pFirstChunk != NULL );
ecma_ArrayFirstChunk_t *pFirstChunkCopy = ecma_AllocArrayFirstChunk(); ecma_ArrayFirstChunk_t *pFirstChunkCopy = ecma_AllocArrayFirstChunk();
libc_memcpy( pFirstChunkCopy, pFirstChunk, sizeof (ecma_ArrayFirstChunk_t)); __memcpy( pFirstChunkCopy, pFirstChunk, sizeof (ecma_ArrayFirstChunk_t));
ecma_ArrayNonFirstChunk_t *pNonFirstChunk, *pNonFirstChunkCopy; ecma_ArrayNonFirstChunk_t *pNonFirstChunk, *pNonFirstChunkCopy;
pNonFirstChunk = ecma_GetPointer( pFirstChunk->m_Header.m_pNextChunk); pNonFirstChunk = ecma_GetPointer( pFirstChunk->m_Header.m_pNextChunk);
@@ -319,7 +319,7 @@ ecma_DuplicateEcmaString( ecma_ArrayFirstChunk_t *pFirstChunk) /**< first chunk
ecma_SetPointer( *pNextPointer, pNonFirstChunkCopy); ecma_SetPointer( *pNextPointer, pNonFirstChunkCopy);
pNextPointer = &pNonFirstChunkCopy->m_pNextChunk; pNextPointer = &pNonFirstChunkCopy->m_pNextChunk;
libc_memcpy( pNonFirstChunkCopy, pNonFirstChunk, sizeof (ecma_ArrayNonFirstChunk_t)); __memcpy( pNonFirstChunkCopy, pNonFirstChunk, sizeof (ecma_ArrayNonFirstChunk_t));
pNonFirstChunk = ecma_GetPointer( pNonFirstChunk->m_pNextChunk); pNonFirstChunk = ecma_GetPointer( pNonFirstChunk->m_pNextChunk);
} }
+53
View File
@@ -0,0 +1,53 @@
/* 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.
*/
/* This allocator only allocates a memmory and doesn't free it.
Use it only in dedicated parser, otherwise use jerry fixed pool allocator. */
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include "../globals.h"
#define ALLOCATION_BUFFER_SIZE 4096
char allocation_buffer[ALLOCATION_BUFFER_SIZE];
char *free_memory;
static void *
geppetto_allocate_memory (size_t size)
{
void *res;
if (!free_memory)
free_memory = allocation_buffer;
res = free_memory;
free_memory += size;
JERRY_ASSERT (free_memory - allocation_buffer < ALLOCATION_BUFFER_SIZE);
return res;
}
static inline void *
malloc (size_t size)
{
return geppetto_allocate_memory (size);
}
static inline void
free (void *mem __unused)
{
JERRY_UNREACHABLE ();
}
#endif // ALLOCATOR_H
+215 -204
View File
@@ -13,96 +13,90 @@
* limitations under the License. * limitations under the License.
*/ */
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "error.h" #include "error.h"
#include "lexer.h" #include "lexer.h"
#include "mappings.h"
static token saved_token; static token saved_token;
static token empty_token = { .type = TOK_EMPTY, .data.none = NULL };
#ifdef DEBUG typedef struct
{
const char *str;
token tok;
}
string_and_token;
static string_and_token keyword_tokens[] =
{
{ .str = "break", .tok = { .type = TOK_KEYWORD, .data.kw = KW_BREAK } },
{ .str = "case", .tok = { .type = TOK_KEYWORD, .data.kw = KW_CASE } },
{ .str = "catch", .tok = { .type = TOK_KEYWORD, .data.kw = KW_CATCH } },
{ .str = "class", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "const", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "continue", .tok = { .type = TOK_KEYWORD, .data.kw = KW_CONTINUE } },
{ .str = "debugger", .tok = { .type = TOK_KEYWORD, .data.kw = KW_DEBUGGER } },
{ .str = "default", .tok = { .type = TOK_KEYWORD, .data.kw = KW_DEFAULT } },
{ .str = "delete", .tok = { .type = TOK_KEYWORD, .data.kw = KW_DELETE } },
{ .str = "do", .tok = { .type = TOK_KEYWORD, .data.kw = KW_DO } },
{ .str = "else", .tok = { .type = TOK_KEYWORD, .data.kw = KW_ELSE } },
{ .str = "enum", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "export", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "extends", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "false", .tok = { .type = TOK_BOOL, .data.is_true = false } },
{ .str = "finally", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FINALLY } },
{ .str = "for", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FOR } },
{ .str = "function", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FUNCTION } },
{ .str = "if", .tok = { .type = TOK_KEYWORD, .data.kw = KW_IF } },
{ .str = "instanceof", .tok = { .type = TOK_KEYWORD, .data.kw = KW_INSTANCEOF } },
{ .str = "interface", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "in", .tok = { .type = TOK_KEYWORD, .data.kw = KW_IN } },
{ .str = "import", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "implements", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "let", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "new", .tok = { .type = TOK_KEYWORD, .data.kw = KW_NEW } },
{ .str = "null", .tok = { .type = TOK_NULL, .data.none = NULL } },
{ .str = "package", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "private", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "protected", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "public", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "return", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RETURN } },
{ .str = "static", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "super", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
{ .str = "switch", .tok = { .type = TOK_KEYWORD, .data.kw = KW_SWITCH } },
{ .str = "this", .tok = { .type = TOK_KEYWORD, .data.kw = KW_THIS } },
{ .str = "throw", .tok = { .type = TOK_KEYWORD, .data.kw = KW_THROW } },
{ .str = "true", .tok = { .type = TOK_BOOL, .data.is_true = true } },
{ .str = "try", .tok = { .type = TOK_KEYWORD, .data.kw = KW_TRY } },
{ .str = "typeof", .tok = { .type = TOK_KEYWORD, .data.kw = KW_TYPEOF } },
{ .str = "var", .tok = { .type = TOK_KEYWORD, .data.kw = KW_VAR } },
{ .str = "void", .tok = { .type = TOK_KEYWORD, .data.kw = KW_VOID } },
{ .str = "while", .tok = { .type = TOK_KEYWORD, .data.kw = KW_WHILE } },
{ .str = "with", .tok = { .type = TOK_KEYWORD, .data.kw = KW_WITH } },
{ .str = "yield", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } }
};
#define MAX_NAMES 100
static string_and_token seen_names[MAX_NAMES];
static size_t seen_names_num;
static inline bool
is_empty (token tok)
{
return tok.type == TOK_EMPTY;
}
#ifdef JERRY_NDEBUG
FILE *lexer_debug_log; FILE *lexer_debug_log;
#endif #endif
/* If TOKEN represents a keyword, return decoded keyword, #ifdef JERRY_NDEBUG
if TOKEN represents a Future Reserved Word, return KW_RESERVED,
otherwise return KW_NONE. */
static keyword
decode_keyword (const char *tok)
{
assert (tok);
if (!strcmp ("break", tok))
return KW_BREAK;
else if (!strcmp ("case", tok))
return KW_CASE;
else if (!strcmp ("catch", tok))
return KW_CATCH;
else if (!strcmp ("continue", tok))
return KW_CONTINUE;
else if (!strcmp ("debugger", tok))
return KW_DEBUGGER;
else if (!strcmp ("default", tok))
return KW_DEFAULT;
else if (!strcmp ("delete", tok))
return KW_DELETE;
else if (!strcmp ("do", tok))
return KW_DO;
else if (!strcmp ("else", tok))
return KW_ELSE;
else if (!strcmp ("finally", tok))
return KW_FINALLY;
else if (!strcmp ("for", tok))
return KW_FOR;
else if (!strcmp ("function", tok))
return KW_FUNCTION;
else if (!strcmp ("if", tok))
return KW_IF;
else if (!strcmp ("in", tok))
return KW_IN;
else if (!strcmp ("instanceof", tok))
return KW_INSTANCEOF;
else if (!strcmp ("new", tok))
return KW_NEW;
else if (!strcmp ("return", tok))
return KW_RETURN;
else if (!strcmp ("switch", tok))
return KW_SWITCH;
else if (!strcmp ("this", tok))
return KW_THIS;
else if (!strcmp ("throw", tok))
return KW_THROW;
else if (!strcmp ("try", tok))
return KW_TRY;
else if (!strcmp ("typeof", tok))
return KW_TYPEOF;
else if (!strcmp ("var", tok))
return KW_VAR;
else if (!strcmp ("void", tok))
return KW_VOID;
else if (!strcmp ("while", tok))
return KW_WHILE;
else if (!strcmp ("with", tok))
return KW_WITH;
else if (!strcmp ("class", tok) || !strcmp ("const", tok)
|| !strcmp ("enum", tok) || !strcmp ("export", tok)
|| !strcmp ("extends", tok) || !strcmp ("import", tok)
|| !strcmp ("super", tok) || !strcmp ("implements", tok)
|| !strcmp ("interface", tok) || !strcmp ("let", tok)
|| !strcmp ("package", tok) || !strcmp ("private", tok)
|| !strcmp ("protected", tok) || !strcmp ("public", tok)
|| !strcmp ("static", tok) || !strcmp ("yield", tok))
return KW_RESERVED;
else
return KW_NONE;
}
static FILE *file; static FILE *file;
static char *buffer_start;
/* Represents the contents of a file. */ /* Represents the contents of a file. */
static char *buffer = NULL; static char *buffer = NULL;
static char *buffer_start;
static char *token_start; static char *token_start;
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
@@ -113,7 +107,7 @@ get_char (int i)
int error; int error;
const int tail_size = BUFFER_SIZE - (buffer - buffer_start); const int tail_size = BUFFER_SIZE - (buffer - buffer_start);
assert (file); JERRY_ASSERT (file);
if (buffer == NULL) if (buffer == NULL)
{ {
@@ -171,25 +165,75 @@ get_char (int i)
#define LA(I) (get_char (I)) #define LA(I) (get_char (I))
#else
/* Represents the contents of a file. */
static const char *buffer = NULL;
static const char *token_start;
#define LA(I) (*(buffer + I))
#endif // JERRY_NDEBUG
/* If TOKEN represents a keyword, return decoded keyword,
if TOKEN represents a Future Reserved Word, return KW_RESERVED,
otherwise return KW_NONE. */
static token
decode_keyword ()
{
size_t size = sizeof (keyword_tokens) / sizeof (string_and_token);
size_t i;
for (i = 0; i < size; i++)
{
if (!strncmp (keyword_tokens[i].str, token_start, strlen (keyword_tokens[i].str)))
return keyword_tokens[i].tok;
}
return empty_token;
}
static token
convert_seen_name_to_token ()
{
size_t i;
for (i = 0; i < seen_names_num; i++)
{
if (!strncmp (seen_names[i].str, token_start, strlen (seen_names[i].str)))
return seen_names[i].tok;
}
return empty_token;
}
static void
add_to_seen_tokens (string_and_token snt)
{
JERRY_ASSERT (seen_names_num < MAX_NAMES);
seen_names[seen_names_num++] = snt;
}
static inline void static inline void
new_token () new_token ()
{ {
assert (buffer); JERRY_ASSERT (buffer);
token_start = buffer; token_start = buffer;
} }
static inline void static inline void
consume_char () consume_char ()
{ {
assert (buffer); JERRY_ASSERT (buffer);
buffer++; buffer++;
} }
static inline const char * static inline const char *
current_token () current_token ()
{ {
assert (buffer); JERRY_ASSERT (buffer);
assert (token_start); JERRY_ASSERT (token_start);
int length = buffer - token_start; int length = buffer - token_start;
char *res = (char *) malloc (length + 1); char *res = (char *) malloc (length + 1);
strncpy (res, token_start, length); strncpy (res, token_start, length);
@@ -237,10 +281,11 @@ static token
parse_name () parse_name ()
{ {
char c = LA (0); char c = LA (0);
bool every_char_islower = isalpha (c) && islower (c); bool every_char_islower = islower (c);
const char *tok = NULL; const char *string = NULL;
token known_token = empty_token;
assert (isalpha (c) || c == '$' || c == '_'); JERRY_ASSERT (isalpha (c) || c == '$' || c == '_');
new_token (); new_token ();
consume_char (); consume_char ();
@@ -251,68 +296,34 @@ parse_name ()
c = c; c = c;
if (!isalpha (c) && !isdigit (c) && c != '$' && c != '_') if (!isalpha (c) && !isdigit (c) && c != '$' && c != '_')
break; break;
if (every_char_islower && (!isalpha (c) || !islower (c))) if (every_char_islower && (!islower (c)))
every_char_islower = false; every_char_islower = false;
consume_char (); consume_char ();
} }
tok = current_token ();
if (every_char_islower) if (every_char_islower)
{ {
keyword kw = decode_keyword (tok); known_token = decode_keyword ();
if (kw != KW_NONE) if (!is_empty (known_token))
{ {
free ((char *) tok); token_start = NULL;
return known_token;
return (token)
{
.type = TOK_KEYWORD, .data.kw = kw
};
}
if (!strcmp ("null", tok))
{
free ((char *) tok);
return (token)
{
.type = TOK_NULL, .data.none = NULL
};
}
if (!strcmp ("true", tok))
{
free ((char *) tok);
return (token)
{
.type = TOK_BOOL, .data.is_true = true
};
}
if (!strcmp ("false", tok))
{
free ((char *) tok);
return (token)
{
.type = TOK_BOOL, .data.is_true = false
};
} }
} }
return (token) known_token = convert_seen_name_to_token ();
if (!is_empty (known_token))
{ {
.type = TOK_NAME, .data.name = tok token_start = NULL;
}; return known_token;
} }
static bool string = current_token ();
is_hex_digit (char c) known_token = (token) { .type = TOK_NAME, .data.name = string };
{
return isdigit (c) || c == 'a' || c == 'A' || c == 'b' || c == 'B' add_to_seen_tokens ((string_and_token) { .str = string, .tok = known_token });
|| c == 'c' || c == 'C' || c == 'd' || c == 'D'
|| c == 'e' || c == 'E' || c == 'f' || c == 'F'; return known_token;
} }
static int static int
@@ -342,7 +353,7 @@ hex_to_int (char hex)
case 'E': return 0xE; case 'E': return 0xE;
case 'f': case 'f':
case 'F': return 0xF; case 'F': return 0xF;
default: unreachable (); default: JERRY_UNREACHABLE ();
} }
} }
@@ -355,11 +366,10 @@ parse_number ()
bool is_hex = false; bool is_hex = false;
bool is_fp = false; bool is_fp = false;
bool is_exp = false; bool is_exp = false;
const char *tok = NULL;
int tok_length = 0; int tok_length = 0;
int res = 0; int res = 0;
assert (isdigit (c) || c == '.'); JERRY_ASSERT (isdigit (c) || c == '.');
if (c == '0') if (c == '0')
if (LA (1) == 'x' || LA (1) == 'X') if (LA (1) == 'x' || LA (1) == 'X')
@@ -367,7 +377,7 @@ parse_number ()
if (c == '.') if (c == '.')
{ {
assert (!isalpha (LA (1))); JERRY_ASSERT (!isalpha (LA (1)));
is_fp = true; is_fp = true;
} }
@@ -380,7 +390,7 @@ parse_number ()
while (true) while (true)
{ {
c = LA (0); c = LA (0);
if (!is_hex_digit (c)) if (!isxdigit (c))
break; break;
consume_char (); consume_char ();
} }
@@ -389,20 +399,15 @@ parse_number ()
fatal (ERR_INT_LITERAL); fatal (ERR_INT_LITERAL);
tok_length = buffer - token_start; tok_length = buffer - token_start;
tok = current_token ();
// OK, I know that integer overflow can occur here // OK, I know that integer overflow can occur here
for (int i = 0; i < tok_length; i++) for (int i = 0; i < tok_length; i++)
res = (res << 4) + hex_to_int (tok[i]); res = (res << 4) + hex_to_int (token_start[i]);
free ((char *) tok); token_start = NULL;
return (token) { .type = TOK_INT, .data.num = res };
return (token)
{
.type = TOK_INT, .data.num = res
};
} }
assert (!is_hex && !is_exp); JERRY_ASSERT (!is_hex && !is_exp);
new_token (); new_token ();
@@ -449,28 +454,18 @@ parse_number ()
if (is_fp || is_exp) if (is_fp || is_exp)
{ {
tok = current_token (); float res = strtof (token_start, NULL);
float res = strtof (tok, NULL); token_start = NULL;
free ((char *) tok); return (token) { .type = TOK_FLOAT, .data.fp_num = res };
return (token)
{
.type = TOK_FLOAT, .data.fp_num = res
};
} }
tok_length = buffer - token_start; tok_length = buffer - token_start;
tok = current_token ();
for (int i = 0; i < tok_length; i++) for (int i = 0; i < tok_length; i++)
res = res * 10 + hex_to_int (tok[i]); res = res * 10 + hex_to_int (token_start[i]);
free ((char *) tok); token_start = NULL;
return (token) return (token) { .type = TOK_INT, .data.num = res };
{
.type = TOK_INT, .data.num = res
};
} }
static char static char
@@ -499,8 +494,9 @@ parse_string ()
char *tok = NULL; char *tok = NULL;
char *index = NULL; char *index = NULL;
int length; int length;
token res = empty_token;
assert (c == '\'' || c == '"'); JERRY_ASSERT (c == '\'' || c == '"');
is_double_quoted = (c == '"'); is_double_quoted = (c == '"');
@@ -540,7 +536,7 @@ parse_string ()
tok = (char *) malloc (length); tok = (char *) malloc (length);
index = tok; index = tok;
for (char *i = token_start; i < buffer; i++) for (const char *i = token_start; i < buffer; i++)
{ {
if (*i == '\\') if (*i == '\\')
{ {
@@ -565,10 +561,11 @@ parse_string ()
// Eat up '"' // Eat up '"'
consume_char (); consume_char ();
return (token) res = (token) { .type = TOK_STRING, .data.str = tok };
{
.type = TOK_STRING, .data.str = tok add_to_seen_tokens ((string_and_token) { .str = tok, .tok = res });
};
return res;
} }
static void static void
@@ -583,15 +580,24 @@ grobble_whitespaces ()
} }
} }
#ifdef JERRY_NDEBUG
void void
lexer_set_file (FILE *ex_file) lexer_set_file (FILE *ex_file)
{ {
assert (ex_file); JERRY_ASSERT (ex_file);
file = ex_file; file = ex_file;
#ifdef DEBUG
lexer_debug_log = fopen ("lexer.log", "w"); lexer_debug_log = fopen ("lexer.log", "w");
#endif saved_token = empty_token;
} }
#else
void
lexer_set_source (const char * source)
{
buffer = source;
saved_token = empty_token;
}
#endif
static bool static bool
replace_comment_by_newline () replace_comment_by_newline ()
@@ -600,8 +606,8 @@ replace_comment_by_newline ()
bool multiline; bool multiline;
bool was_newlines = false; bool was_newlines = false;
assert (LA (0) == '/'); JERRY_ASSERT (LA (0) == '/');
assert (LA (1) == '/' || LA (1) == '*'); JERRY_ASSERT (LA (1) == '/' || LA (1) == '*');
multiline = (LA (1) == '*'); multiline = (LA (1) == '*');
@@ -631,7 +637,7 @@ replace_comment_by_newline ()
} }
token token
#ifdef DEBUG #ifdef JERRY_NDEBUG
lexer_next_token_private () lexer_next_token_private ()
#else #else
lexer_next_token () lexer_next_token ()
@@ -639,14 +645,14 @@ lexer_next_token ()
{ {
char c = LA (0); char c = LA (0);
if (saved_token.type != TOK_EOF) if (!is_empty (saved_token))
{ {
token res = saved_token; token res = saved_token;
saved_token.type = TOK_EOF; saved_token = empty_token;
return res; return res;
} }
assert (token_start == NULL); JERRY_ASSERT (token_start == NULL);
if (isalpha (c) || c == '$' || c == '_') if (isalpha (c) || c == '$' || c == '_')
return parse_name (); return parse_name ();
@@ -657,18 +663,11 @@ lexer_next_token ()
if (c == '\n') if (c == '\n')
{ {
consume_char (); consume_char ();
return (token) { .type = TOK_NEWLINE, .data.none = NULL };
return (token)
{
.type = TOK_NEWLINE, .data.none = NULL
};
} }
if (c == '\0') if (c == '\0')
return (token) return (token) { .type = TOK_EOF, .data.none = NULL };;
{
.type = TOK_EOF, .data.none = NULL
};
if (c == '\'' || c == '"') if (c == '\'' || c == '"')
return parse_string (); return parse_string ();
@@ -676,24 +675,36 @@ lexer_next_token ()
if (isspace (c)) if (isspace (c))
{ {
grobble_whitespaces (); grobble_whitespaces ();
return lexer_next_token (); return
#ifdef JERRY_NDEBUG
lexer_next_token_private ();
#else
lexer_next_token ();
#endif
} }
if (c == '/' && LA (1) == '*') if (c == '/' && LA (1) == '*')
{ {
if (replace_comment_by_newline ()) if (replace_comment_by_newline ())
return (token) return (token) { .type = TOK_NEWLINE, .data.none = NULL };
{
.type = TOK_NEWLINE, .data.none = NULL
};
else else
return lexer_next_token (); return
#ifdef JERRY_NDEBUG
lexer_next_token_private ();
#else
lexer_next_token ();
#endif
} }
if (c == '/' && LA (1) == '/') if (c == '/' && LA (1) == '/')
{ {
replace_comment_by_newline (); replace_comment_by_newline ();;
return lexer_next_token (); return
#ifdef JERRY_NDEBUG
lexer_next_token_private ();
#else
lexer_next_token ();
#endif
} }
switch (c) switch (c)
@@ -756,12 +767,12 @@ lexer_next_token ()
RETURN_PUNC (TOK_NOT); RETURN_PUNC (TOK_NOT);
default: default:
unreachable (); JERRY_UNREACHABLE ();
} }
fatal (ERR_NON_CHAR); fatal (ERR_NON_CHAR);
} }
#ifdef DEBUG #ifdef JERRY_NDEBUG
static int i = 0; static int i = 0;
token token
@@ -770,9 +781,9 @@ lexer_next_token ()
token tok = lexer_next_token_private (); token tok = lexer_next_token_private ();
if (tok.type == TOK_NEWLINE) if (tok.type == TOK_NEWLINE)
return tok; return tok;
if (tok.type == TOK_CLOSE_BRACE) // if (tok.type == TOK_CLOSE_BRACE)
{ {
if (i == 300) // if (i == 300)
fprintf (lexer_debug_log, "lexer_next_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none); fprintf (lexer_debug_log, "lexer_next_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none);
i++; i++;
} }
@@ -783,8 +794,8 @@ lexer_next_token ()
void void
lexer_save_token (token tok) lexer_save_token (token tok)
{ {
#ifdef DEBUG #ifdef JERRY_NDEBUG
if (tok.type == TOK_CLOSE_BRACE) // if (tok.type == TOK_CLOSE_BRACE)
fprintf (lexer_debug_log, "lexer_save_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none); fprintf (lexer_debug_log, "lexer_save_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none);
#endif #endif
saved_token = tok; saved_token = tok;
@@ -793,5 +804,5 @@ lexer_save_token (token tok)
void void
lexer_dump_buffer_state () lexer_dump_buffer_state ()
{ {
//printf ("%s\n", buffer); printf ("%s\n", buffer);
} }
+7 -3
View File
@@ -16,8 +16,7 @@
#ifndef LEXER_H #ifndef LEXER_H
#define LEXER_H #define LEXER_H
#include <stdbool.h> #include "mappings.h"
#include <stdio.h>
/* Keywords. */ /* Keywords. */
typedef enum typedef enum
@@ -128,7 +127,8 @@ typedef enum
TOK_XOR_EQ, // ^= TOK_XOR_EQ, // ^=
TOK_DIV, // / TOK_DIV, // /
TOK_DIV_EQ // /= TOK_DIV_EQ, // /=
TOK_EMPTY
} }
token_type; token_type;
@@ -151,7 +151,11 @@ typedef struct
} }
token; token;
#ifdef JERRY_NDEBUG
void lexer_set_file (FILE *); void lexer_set_file (FILE *);
#else
void lexer_set_source (const char *);
#endif
token lexer_next_token (); token lexer_next_token ();
void lexer_save_token (token); void lexer_save_token (token);
+139
View File
@@ -0,0 +1,139 @@
/* 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 MAPPINGS_H
#define MAPPINGS_H
#ifndef JERRY_NDEBUG
#include "../jerry-libc.h"
#include "allocator.h"
#include <stdarg.h>
static inline void *
memset (void *s, int n1, size_t n2)
{
return __memset (s, n1, n2);
}
static inline int
memcmp (const void *s1, const void *s2, size_t n)
{
return __memcmp (s1, s2, n);
}
static inline void *
memcpy (void *s1, const void *s2, size_t n)
{
return __memcpy (s1, s2, n);
}
static inline int
printf (const char *s, ...)
{
va_list args;
va_start (args, s);
int ret = __printf (s, args);
va_end (args);
return ret;
}
static inline int
putchar (int c)
{
return __putchar (c);
}
static inline void
exit (int status)
{
return __exit (status);
}
static inline int
strcmp (const char *s1, const char *s2)
{
return __strcmp (s1, s2);
}
static inline int
strncmp (const char *s1, const char *s2, size_t n)
{
return __strncmp (s1, s2, n);
}
static inline char *
strncpy (char *s1, const char *s2, size_t n)
{
return __strncpy (s1, s2, n);
}
static inline float
strtof (const char *s1, char **s2)
{
return __strtof (s1, s2);
}
static inline size_t
strlen (const char *s)
{
return __strlen (s);
}
static inline int
isspace (int s)
{
return __isspace (s);
}
static inline int
isupper (int s)
{
return __isupper (s);
}
static inline int
islower (int s)
{
return __islower (s);
}
static inline int
isalpha (int s)
{
return __isalpha (s);
}
static inline int
isdigit (int s)
{
return __isdigit (s);
}
static inline int
isxdigit (int s)
{
return __isxdigit (s);
}
#else
#undef NULL
#include "../globals.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#endif
#endif // MAPPINGS_H
+582 -1324
View File
File diff suppressed because it is too large Load Diff
+264 -529
View File
@@ -16,8 +16,7 @@
#ifndef PARSER_H #ifndef PARSER_H
#define PARSER_H #define PARSER_H
#include <stdio.h> #include "mappings.h"
#include <stdbool.h>
struct source_element_list; struct source_element_list;
struct statement_list; struct statement_list;
@@ -25,16 +24,32 @@ struct statement;
struct assignment_expression; struct assignment_expression;
struct member_expression; struct member_expression;
#define MAX_PARAMS 5
#define MAX_EXPRS 2
#define MAX_PROPERTIES 5
#define MAX_DECLS 5
#define MAX_SUFFIXES 2
/** Represents list of parameters. */ /** Represents list of parameters. */
typedef struct formal_parameter_list typedef struct formal_parameter_list
{ {
/** Identifier of a parameter. Cannot be NULL. */ /** Identifiers of a parameter. Next after last parameter is NULL. */
const char *name; const char *names[MAX_PARAMS];
/** Next parameter: can be NULL. */
struct formal_parameter_list *next;
} }
formal_parameter_list; formal_parameter_list;
static const formal_parameter_list
empty_formal_parameter_list =
{
.names = { [0] = NULL}
};
static inline bool
is_formal_parameter_list_empty (formal_parameter_list list)
{
return list.names[0] == NULL;
}
/** @function_declaration represents both declaration and expression of a function. /** @function_declaration represents both declaration and expression of a function.
After this parser must return a block of statements. */ After this parser must return a block of statements. */
typedef struct typedef struct
@@ -42,27 +57,12 @@ typedef struct
/** Identifier: name of a function. Can be NULL for anonimous functions. */ /** Identifier: name of a function. Can be NULL for anonimous functions. */
const char *name; const char *name;
/** List of parameter of a function. Can be NULL. */ /** List of parameter of a function. Can be NULL. */
formal_parameter_list *params; formal_parameter_list params;
} }
function_declaration; function_declaration;
typedef function_declaration function_expression; typedef function_declaration function_expression;
/** Represents expression, array literal and list of argument. */
typedef struct expression_list
{
/** Single assignment expression. Cannot be NULL for expression and list of arguments.
But can be NULL for array literal. */
struct assignment_expression *assign_expr;
/** Next expression. Can be NULL. */
struct expression_list *next;
}
expression_list;
typedef expression_list expression;
typedef expression_list array_literal;
typedef expression_list argument_list;
/** Types of literals: null, bool, decimal and string. /** Types of literals: null, bool, decimal and string.
Decimal type is represented by LIT_INT and supports only double-word sized integers. */ Decimal type is represented by LIT_INT and supports only double-word sized integers. */
typedef enum typedef enum
@@ -84,7 +84,7 @@ typedef struct
union union
{ {
/** Used by null literal, always NULL. */ /** Used by null literal, always NULL. */
void *data; void *none;
/** String literal value. */ /** String literal value. */
const char *str; const char *str;
/** Number value. */ /** Number value. */
@@ -96,536 +96,257 @@ typedef struct
} }
literal; literal;
/** type of PropertyName. Can be integer, identifier of string literal. */
typedef enum
{
PN_NAME,
PN_STRING,
PN_NUM
}
property_name_type;
/** Represents name of property. */
typedef struct typedef struct
{ {
/** Type of property name. */ bool is_literal;
property_name_type type;
/** Value of property name. */
union union
{ {
/** Identifier. */ void *none;
literal lit;
const char *name; const char *name;
/** Value of string literal. */
const char *str;
/** Numeric value. */
int num;
} }
data; data;
} }
property_name; operand;
typedef operand property_name;
static const operand
empty_operand =
{
.is_literal = false,
.data.none = NULL
};
static inline bool
is_operand_empty (operand op)
{
return op.is_literal == false && op.data.none == NULL;
}
typedef struct
{
operand op1, op2;
}
operand_pair;
typedef struct
{
operand ops[MAX_PARAMS];
}
operand_list;
static const operand_list
empty_operand_list =
{
.ops = { [0] = { .is_literal = false, .data.none = NULL } }
};
static inline bool
is_operand_list_empty (operand_list list)
{
return is_operand_empty (list.ops[0]);
}
typedef operand_list array_literal;
typedef operand_list argument_list;
typedef struct
{
const char *name;
argument_list args;
}
call_expression;
/** Represents a single property. */ /** Represents a single property. */
typedef struct typedef struct
{ {
/** Name of property. */ /** Name of property. */
property_name *name; property_name name;
/** Value of property. */ /** Value of property. */
struct assignment_expression *assign_expr; operand value;
}
property;
static const property empty_property =
{
.name = { .is_literal = false, .data.none = NULL },
.value = { .is_literal = false, .data.none = NULL }
};
static inline bool
is_property_empty (property prop)
{
return is_operand_empty (prop.name) && is_operand_empty (prop.value);
} }
property_name_and_value;
/** List of properties. Represents ObjectLiteral. */ /** List of properties. Represents ObjectLiteral. */
typedef struct property_name_and_value_list
{
/** Current property. */
property_name_and_value *nav;
/** Next property. */
struct property_name_and_value_list *next;
}
property_name_and_value_list;
typedef property_name_and_value_list object_literal;
/** Type of PrimaryExpression. Can be ThisLiteral, Identifier, Literal, ArrayLiteral,
ObjectLiteral or expression. */
typedef enum
{
PE_THIS,
PE_NAME,
PE_LITERAL,
PE_ARRAY,
PE_OBJECT,
PE_EXPR
}
primary_expression_type;
/** PrimaryExpression. */
typedef struct typedef struct
{ {
/** Type of PrimaryExpression. */ /** Properties. */
primary_expression_type type; property props[MAX_PROPERTIES];
}
property_list;
static const property_list
empty_property_list =
{
.props =
{ [0] =
{ .name =
{ .is_literal = false, .data.none = NULL },
.value =
{ .is_literal = false, .data.none = NULL }}}
};
static inline bool
is_property_list_empty (property_list list)
{
return is_property_empty (list.props[0]);
}
typedef property_list object_literal;
typedef enum
{
AO_NONE,
AO_EQ,
AO_MULT_EQ,
AO_DIV_EQ,
AO_MOD_EQ,
AO_PLUS_EQ,
AO_MINUS_EQ,
AO_LSHIFT_EQ,
AO_RSHIFT_EQ,
AO_RSHIFT_EX_EQ,
AO_AND_EQ,
AO_XOR_EQ,
AO_OR_EQ
}
assignment_operator;
typedef enum
{
ET_NONE,
ET_LOGICAL_OR,
ET_LOGICAL_AND,
ET_BITWISE_OR,
ET_BITWISE_XOR,
ET_BITWISE_AND,
ET_DOUBLE_EQ,
ET_NOT_EQ,
ET_TRIPLE_EQ,
ET_NOT_DOUBLE_EQ,
ET_LESS,
ET_GREATER,
ET_LESS_EQ,
ET_GREATER_EQ,
ET_INSTANCEOF,
ET_IN,
ET_LSHIFT,
ET_RSHIFT,
ET_RSHIFT_EX,
ET_PLUS,
ET_MINUS,
ET_MULT,
ET_DIV,
ET_MOD,
ET_UNARY_DELETE,
ET_UNARY_VOID,
ET_UNARY_TYPEOF,
ET_UNARY_INCREMENT,
ET_UNARY_DECREMENT,
ET_UNARY_PLUS,
ET_UNARY_MINUS,
ET_UNARY_COMPL,
ET_UNARY_NOT,
ET_POSTFIX_INCREMENT,
ET_POSTFIX_DECREMENT,
ET_CALL,
ET_NEW,
ET_INDEX,
ET_PROP_REF,
ET_OBJECT,
ET_FUNCTION,
ET_ARRAY,
ET_SUBEXPRESSION,
ET_LITERAL,
ET_IDENTIFIER
}
expression_type;
typedef struct
{
assignment_operator oper;
expression_type type;
/** NUllable. */
const char *var;
/** Value of PrimaryExpression. */
union union
{ {
/** Used for ThisLiteral. Always NULL. */
void *none; void *none;
/** Identifier. */ operand_pair ops;
const char *name; call_expression call_expr;
/** Literal. */ array_literal arr_lit;
literal *lit; object_literal obj_lit;
/** ArrayLiteral. */ function_expression func_expr;
array_literal *array_lit;
/** ObjectLiteral. */
object_literal *object_lit;
/** Expression. */
expression *expr;
}
data;
}
primary_expression;
/** Type of suffix of MemberExpression. Can be either index-like ([]) or property-like (.). */
typedef enum
{
MES_INDEX,
MES_PROPERTY
}
member_expression_suffix_type;
/** Suffix of MemberExpression. */
typedef struct
{
/** Type of suffix. */
member_expression_suffix_type type;
/** Value of suffix. */
union
{
/** Used by index-like suffix. */
expression *index_expr;
/** Used by property-like suffix. */
const char *name;
}
data;
}
member_expression_suffix;
/** List of MemberExpression's suffixes. */
typedef struct member_expression_suffix_list
{
/** Current suffix. */
member_expression_suffix *suffix;
/** Next suffix. */
struct member_expression_suffix_list *next;
}
member_expression_suffix_list;
/** Represents MemberExpression Arguments grammar production. */
typedef struct
{
/** MemberExpression. */
struct member_expression *member_expr;
/** Arguments. */
argument_list *args;
}
member_expression_with_arguments;
/** Types of MemberExpression. Can be PrimaryExpression,
FunctionExpression or MemberExpression Arguments. */
typedef enum
{
ME_PRIMARY,
ME_FUNCTION,
ME_ARGS
}
member_expression_type;
/** Represents MemberExpression. */
typedef struct member_expression
{
/** Type of MemberExpression. */
member_expression_type type;
/** Value of MemberExpression. */
union
{
/** PrimaryExpression. */
primary_expression *primary_expr;
/** FunctionExpression. */
function_expression *function_expr;
/** MemberExpression Arguments. */
member_expression_with_arguments *args;
}
data;
member_expression_suffix_list *suffix_list;
}
member_expression;
/** Types of NewExpression. Can be either MemberExpression or NewExpression. */
typedef enum
{
NE_MEMBER,
NE_NEW
}
new_expression_type;
/** Represents NewExpression. */
typedef struct new_expression
{
/** Type of NewExpression. */
new_expression_type type;
/** Value of NewExpression. */
union
{
/** MemberExpression. */
member_expression *member_expr;
/** NewExpression. */
struct new_expression *new_expr;
}
data;
}
new_expression;
/** Types of CallExpression' suffix. Can be Arguments, index-like access ([]) or
property-like access (.). */
typedef enum
{
CAS_ARGS,
CAS_INDEX,
CAS_PROPERTY
}
call_expression_suffix_type;
/** Suffix of CallExpression. */
typedef struct
{
/** Type of suffix. */
call_expression_suffix_type type;
/** Value of suffix. */
union
{
/** Arguments. */
argument_list *args;
/** index-like access expression. */
expression *index_expr;
/** Identifier of property. */
const char *name;
}
data;
}
call_expression_suffix;
/** List of CallExpression's suffixes. */
typedef struct call_expression_suffix_list
{
/** Current suffix. */
call_expression_suffix *suffix;
/** Next suffix. */
struct call_expression_suffix_list *next;
}
call_expression_suffix_list;
/** CallExpression. */
typedef struct
{
/** Callee. Cannot be NULL. */
member_expression *member_expr;
/** List of arguments. Can be NULL. */
argument_list *args;
/** Suffixes of CallExpression. Can be NULL. */
call_expression_suffix_list *suffix_list;
}
call_expression;
/** Types of LeftHandSideExpression. Can be either CallExpression or NewExpression. */
typedef enum
{
LHSE_CALL,
LHSE_NEW
}
left_hand_side_expression_type;
/** LeftHandSideExpression. */
typedef struct
{
/** Type of LeftHandSideExpression. */
left_hand_side_expression_type type;
/** Value of LeftHandSideExpression. */
union
{
/** Value of CallExpression. */
call_expression *call_expr;
/** Value of NewExpression. */
new_expression *new_expr;
}
data;
}
left_hand_side_expression;
/** Type of PostfixExpression. Unlike ECMA, it can contain no postfix operator in addition to
increment and decrement. */
typedef enum
{
PE_NONE,
PE_INCREMENT,
PE_DECREMENT
}
postfix_expression_type;
/** PostfixExpression. */
typedef struct
{
/** Type of PostfixExpression. */
postfix_expression_type type;
/** LeftHandSideExpression. */
left_hand_side_expression *expr;
}
postfix_expression;
/** Types of UnaryExpression. Can be PostfixExpression, delete UnaryExpression,
void UnaryExpression, typeof UnaryExpression, ++ UnaryExpression, -- UnaryExpression,
+ UnaryExpression, - UnaryExpression, ~ UnaryExpression, ! UnaryExpression. */
typedef enum
{
UE_POSTFIX,
UE_DELETE,
UE_VOID,
UE_TYPEOF,
UE_INCREMENT,
UE_DECREMENT,
UE_PLUS,
UE_MINUS,
UE_COMPL,
UE_NOT
}
unary_expression_type;
/** UnaryExpression. */
typedef struct unary_expression
{
/** Type of UnaryExpression. */
unary_expression_type type;
/** Data of UnaryExpression. */
union
{
/** PostfixExpression. Exists only when type of UE_POSTFIX. */
postfix_expression *postfix_expr;
/** UnaryExpression after an operator. Exists otherwise. */
struct unary_expression *unary_expr;
}
data;
}
unary_expression;
/** Type of MultiplicativeExpression. In addition to ECMA if there is only one operand,
we use ME_NONE. */
typedef enum
{
ME_NONE,
ME_MULT,
ME_DIV,
ME_MOD
}
multiplicative_expression_type;
/** List of MultiplicativeExpressions. It can contain 1..n operands. */
typedef struct multiplicative_expression_list
{
/** Type of current MultiplicativeExpression. */
multiplicative_expression_type type;
/** Current operand. */
unary_expression *unary_expr;
/** Next operand. */
struct multiplicative_expression_list *next;
}
multiplicative_expression_list;
typedef enum
{
AE_NONE,
AE_PLUS,
AE_MINUS
}
additive_expression_type;
typedef struct additive_expression_list
{
additive_expression_type type;
multiplicative_expression_list *mult_expr;
struct additive_expression_list *next;
}
additive_expression_list;
typedef enum
{
SE_NONE,
SE_LSHIFT,
SE_RSHIFT,
SE_RSHIFT_EX
}
shift_expression_type;
typedef struct shift_expression_list
{
shift_expression_type type;
additive_expression_list *add_expr;
struct shift_expression_list *next;
}
shift_expression_list;
typedef enum
{
RE_NONE,
RE_LESS,
RE_GREATER,
RE_LESS_EQ,
RE_GREATER_EQ,
RE_INSTANCEOF,
RE_IN
}
relational_expression_type;
typedef struct relational_expression_list
{
relational_expression_type type;
shift_expression_list *shift_expr;
struct relational_expression_list *next;
}
relational_expression_list;
typedef enum
{
EE_NONE,
EE_DOUBLE_EQ,
EE_NOT_EQ,
EE_TRIPLE_EQ,
EE_NOT_DOUBLE_EQ
}
equality_expression_type;
typedef struct equality_expression_list
{
equality_expression_type type;
relational_expression_list *rel_expr;
struct equality_expression_list *next;
}
equality_expression_list;
typedef struct bitwise_and_expression_list
{
equality_expression_list *eq_expr;
struct bitwise_and_expression_list *next;
}
bitwise_and_expression_list;
typedef struct bitwise_xor_expression_list
{
bitwise_and_expression_list *and_expr;
struct bitwise_xor_expression_list *next;
}
bitwise_xor_expression_list;
typedef struct bitwise_or_expression_list
{
bitwise_xor_expression_list *xor_expr;
struct bitwise_or_expression_list *next;
}
bitwise_or_expression_list;
typedef struct logical_and_expression_list
{
bitwise_or_expression_list *or_expr;
struct logical_and_expression_list *next;
}
logical_and_expression_list;
typedef struct logical_or_expression_list
{
logical_and_expression_list *and_expr;
struct logical_or_expression_list *next;
}
logical_or_expression_list;
typedef struct
{
logical_or_expression_list *or_expr;
struct assignment_expression *then_expr, *else_expr;
}
conditional_expression;
typedef enum
{
AE_COND,
AE_EQ,
AE_MULT_EQ,
AE_DIV_EQ,
AE_MOD_EQ,
AE_PLUS_EQ,
AE_MINUS_EQ,
AE_LSHIFT_EQ,
AE_RSHIFT_EQ,
AE_RSHIFT_EX_EQ,
AE_AND_EQ,
AE_OR_EQ,
AE_XOR_EQ
}
assignment_expression_type;
typedef struct
{
left_hand_side_expression *left_hand_expr;
struct assignment_expression *assign_expr;
}
left_hand_and_assignment_expression;
typedef struct assignment_expression
{
assignment_expression_type type;
union
{
conditional_expression *cond_expr;
left_hand_and_assignment_expression s;
} }
data; data;
} }
assignment_expression; assignment_expression;
static const assignment_expression
empty_expression =
{
.oper = AO_NONE,
.type = ET_NONE,
.data.none = NULL
};
static inline bool
is_expression_empty (assignment_expression expr)
{
return expr.oper == AO_NONE && expr.type == ET_NONE && expr.data.none == NULL;
}
/** Represents expression, array literal and list of argument. */
typedef struct
{
/** Single assignment expression. Cannot be NULL for expression and list of arguments.
But can be NULL for array literal. */
assignment_expression exprs[MAX_EXPRS];
}
expression_list;
typedef expression_list expression;
/* Statements. */ /* Statements. */
typedef struct typedef struct
{ {
const char *name; const char *name;
assignment_expression assign_expr;
assignment_expression *ass_expr;
} }
variable_declaration; variable_declaration;
typedef struct variable_declaration_list static const variable_declaration
empty_variable_declaration =
{ {
variable_declaration *var_decl; .name = NULL,
.assign_expr = { .oper = AO_NONE, .type = ET_NONE, .data.none = NULL }
};
struct variable_declaration_list *next; static inline bool
is_variable_declaration_empty (variable_declaration var_decl)
{
return var_decl.name == NULL && is_expression_empty (var_decl.assign_expr);
}
typedef struct
{
variable_declaration decls[MAX_DECLS];
} }
variable_declaration_list; variable_declaration_list;
@@ -635,8 +356,8 @@ typedef struct
union union
{ {
expression *expr; expression expr;
variable_declaration_list *decl_list; variable_declaration_list decl_list;
} }
data; data;
} }
@@ -644,8 +365,8 @@ for_statement_initialiser_part;
typedef struct typedef struct
{ {
for_statement_initialiser_part *init; for_statement_initialiser_part init;
expression *limit, *incr; assignment_expression limit, incr;
} }
for_statement; for_statement;
@@ -655,8 +376,8 @@ typedef struct
union union
{ {
left_hand_side_expression *left_hand_expr; assignment_expression left_hand_expr;
variable_declaration *decl; variable_declaration decl;
} }
data; data;
} }
@@ -664,8 +385,8 @@ for_in_statement_initializer_part;
typedef struct typedef struct
{ {
for_in_statement_initializer_part *init; for_in_statement_initializer_part init;
expression *list_expr; expression list_expr;
} }
for_in_statement; for_in_statement;
@@ -675,8 +396,8 @@ typedef struct
union union
{ {
for_statement *for_stmt; for_statement for_stmt;
for_in_statement *for_in_stmt; for_in_statement for_in_stmt;
} }
data; data;
} }
@@ -684,6 +405,7 @@ for_or_for_in_statement;
typedef enum typedef enum
{ {
STMT_NULL,
STMT_BLOCK_START, STMT_BLOCK_START,
STMT_BLOCK_END, STMT_BLOCK_END,
STMT_VARIABLE, STMT_VARIABLE,
@@ -722,17 +444,30 @@ typedef struct statement
union union
{ {
void *none; void *none;
variable_declaration_list *var_stmt; variable_declaration_list var_stmt;
expression *expr; expression expr;
for_or_for_in_statement *for_stmt; for_or_for_in_statement for_stmt;
const char *name; const char *name;
function_declaration *fun_decl; function_declaration fun_decl;
} }
data; data;
} }
statement; statement;
static const statement
null_statement =
{
.type = STMT_NULL,
.data.none = NULL
};
static inline bool
is_statement_null (statement stmt)
{
return stmt.type == STMT_NULL && stmt.data.none == NULL;
}
void parser_init (); void parser_init ();
statement *parser_parse_statement (); statement parser_parse_statement ();
#endif #endif
+10 -2
View File
@@ -13,9 +13,11 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef JERRY_NDEBUG
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
#endif
#include "error.h" #include "error.h"
@@ -40,7 +42,9 @@ main (int argc, char **argv)
bool dump_tokens = false; bool dump_tokens = false;
bool dump_ast = true; bool dump_ast = true;
const char *file_name = NULL; const char *file_name = NULL;
#ifdef JERRY_NDEBUG
FILE *file = NULL; FILE *file = NULL;
#endif
mem_Init (); mem_Init ();
ctx_Init (); ctx_Init ();
@@ -64,16 +68,20 @@ main (int argc, char **argv)
if (dump_tokens && dump_ast) if (dump_tokens && dump_ast)
fatal (ERR_SEVERAL_FILES); fatal (ERR_SEVERAL_FILES);
#ifdef JERRY_NDEBUG
file = fopen (file_name, "r"); file = fopen (file_name, "r");
if (file == NULL) if (file == NULL)
{ {
fatal (ERR_IO); fatal (ERR_IO);
} }
#endif
// FIXME: Call parser
//gen_bytecode (generated_source); //gen_bytecode (generated_source);
gen_bytecode (); //gen_bytecode ();
run_int (); //run_int ();
#ifdef __TARGET_MCU #ifdef __TARGET_MCU
fake_exit (); fake_exit ();
+393 -773
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -23,6 +23,6 @@ void pp_reset ();
void pp_finish (); void pp_finish ();
void pp_token (token); void pp_token (token);
void pp_keyword (keyword); void pp_keyword (keyword);
void pp_statement (statement *); void pp_statement (statement);
#endif #endif
+2 -2
View File
@@ -49,7 +49,7 @@ main( int __unused argc,
srand((unsigned int) time(NULL)); srand((unsigned int) time(NULL));
unsigned int seed = (unsigned int)rand(); unsigned int seed = (unsigned int)rand();
libc_printf("seed=%u\n", seed); __printf("seed=%u\n", seed);
srand(seed); srand(seed);
for ( int i = 0; i < test_iters; i++ ) for ( int i = 0; i < test_iters; i++ )
@@ -70,7 +70,7 @@ main( int __unused argc,
if ( ptrs[j] != NULL ) if ( ptrs[j] != NULL )
{ {
libc_memset(ptrs[j], 0, chunkSize); __memset(ptrs[j], 0, chunkSize);
} }
} }