2018-01-21 03:56:50 +00:00
/* Copyright (C) 2016 Jeremiah Orians
2018-08-27 02:15:32 +01:00
* Copyright ( C ) 2018 Jan ( janneke ) Nieuwenhuizen < janneke @ gnu . org >
2020-02-01 20:23:49 +00:00
* Copyright ( C ) 2020 deesix < deesix @ tuta . io >
2018-10-18 00:27:06 +01:00
* This file is part of M2 - Planet .
2018-01-21 03:56:50 +00:00
*
2018-10-18 00:27:06 +01:00
* M2 - Planet is free software : you can redistribute it and / or modify
2018-01-21 03:56:50 +00:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
2018-10-18 00:27:06 +01:00
* M2 - Planet is distributed in the hope that it will be useful ,
2018-01-21 03:56:50 +00:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2018-10-18 00:27:06 +01:00
* along with M2 - Planet . If not , see < http : //www.gnu.org/licenses/>.
2018-01-21 03:56:50 +00:00
*/
# include "cc.h"
2018-07-20 03:33:02 +01:00
# include "gcc_req.h"
2018-01-21 03:56:50 +00:00
# include <stdint.h>
/* Global lists */
struct token_list * global_symbol_list ;
struct token_list * global_function_list ;
struct token_list * global_constant_list ;
2018-08-18 20:23:58 +01:00
/* Core lists for this file */
struct token_list * function ;
2018-01-21 03:56:50 +00:00
/* What we are currently working on */
2018-01-25 01:00:22 +00:00
struct type * current_target ;
2018-06-28 21:40:51 +01:00
char * break_target_head ;
char * break_target_func ;
char * break_target_num ;
2020-02-28 23:48:58 +00:00
char * continue_target_head ;
2018-08-10 22:30:48 +01:00
struct token_list * break_frame ;
2018-06-08 20:43:36 +01:00
int current_count ;
2018-10-17 21:08:04 +01:00
int Address_of ;
2018-01-21 03:56:50 +00:00
/* Imported functions */
2020-01-22 23:03:28 +00:00
char * number_to_hex ( int a , int bytes ) ;
char * numerate_number ( int a ) ;
2018-01-21 03:56:50 +00:00
char * parse_string ( char * string ) ;
2018-06-02 01:05:27 +01:00
int escape_lookup ( char * c ) ;
2019-02-24 22:46:05 +00:00
int numerate_string ( char * a ) ;
2020-01-22 23:03:28 +00:00
void require ( int bool , char * error ) ;
2020-12-19 11:50:11 +00:00
struct token_list * reverse_list ( struct token_list * head ) ;
2021-01-03 03:00:02 +00:00
struct type * mirror_type ( struct type * source , char * name ) ;
struct type * add_primitive ( struct type * a ) ;
2020-10-17 18:50:25 +01:00
/* Host touchy function will need custom on 64bit systems*/
int fixup_int32 ( int a ) ;
2018-08-21 01:41:37 +01:00
2018-01-21 03:56:50 +00:00
struct token_list * emit ( char * s , struct token_list * head )
{
struct token_list * t = calloc ( 1 , sizeof ( struct token_list ) ) ;
2020-01-25 19:15:45 +00:00
require ( NULL ! = t , " Exhusted memory while generating token to emit \n " ) ;
2018-01-21 03:56:50 +00:00
t - > next = head ;
t - > s = s ;
return t ;
}
2018-08-18 20:23:58 +01:00
void emit_out ( char * s )
{
2019-06-04 02:01:14 +01:00
output_list = emit ( s , output_list ) ;
2018-08-18 20:23:58 +01:00
}
struct token_list * uniqueID ( char * s , struct token_list * l , char * num )
{
2019-02-23 23:33:57 +00:00
l = emit ( " \n " , emit ( num , emit ( " _ " , emit ( s , l ) ) ) ) ;
2018-08-18 20:23:58 +01:00
return l ;
}
void uniqueID_out ( char * s , char * num )
{
2019-06-04 02:01:14 +01:00
output_list = uniqueID ( s , output_list , num ) ;
2018-08-18 20:23:58 +01:00
}
2018-01-21 03:56:50 +00:00
struct token_list * sym_declare ( char * s , struct type * t , struct token_list * list )
{
struct token_list * a = calloc ( 1 , sizeof ( struct token_list ) ) ;
2020-01-25 19:15:45 +00:00
require ( NULL ! = a , " Exhusted memory while attempting to declare a symbol \n " ) ;
2018-01-21 03:56:50 +00:00
a - > next = list ;
a - > s = s ;
a - > type = t ;
return a ;
}
struct token_list * sym_lookup ( char * s , struct token_list * symbol_list )
{
2018-01-25 01:00:22 +00:00
struct token_list * i ;
for ( i = symbol_list ; NULL ! = i ; i = i - > next )
2018-01-21 03:56:50 +00:00
{
2018-02-01 04:14:40 +00:00
if ( match ( i - > s , s ) ) return i ;
2018-01-21 03:56:50 +00:00
}
return NULL ;
}
2021-01-05 21:39:25 +00:00
void line_error_token ( struct token_list * token )
2018-08-21 01:41:37 +01:00
{
2021-01-05 21:39:25 +00:00
require ( NULL ! = token , " EOF reached inside of line_error \n " ) ;
file_print ( token - > filename , stderr ) ;
2018-08-27 02:15:32 +01:00
file_print ( " : " , stderr ) ;
2021-01-05 21:39:25 +00:00
file_print ( numerate_number ( token - > linenumber ) , stderr ) ;
2018-08-27 02:15:32 +01:00
file_print ( " : " , stderr ) ;
2018-08-21 01:41:37 +01:00
}
2021-01-05 21:39:25 +00:00
void line_error ( )
{
line_error_token ( global_token ) ;
}
2018-08-21 01:41:37 +01:00
void require_match ( char * message , char * required )
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " EOF reached inside of require match \n " ) ;
2018-08-21 01:41:37 +01:00
if ( ! match ( global_token - > s , required ) )
{
line_error ( ) ;
2018-08-27 02:15:32 +01:00
file_print ( message , stderr ) ;
2018-08-21 01:41:37 +01:00
exit ( EXIT_FAILURE ) ;
}
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " EOF after require match occurred \n " ) ;
2018-08-21 01:41:37 +01:00
}
2021-01-09 23:34:25 +00:00
void maybe_bootstrap_error ( char * feature )
{
if ( BOOTSTRAP_MODE )
{
line_error ( ) ;
file_print ( feature , stderr ) ;
file_print ( " is not supported in --bootstrap-mode \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
}
}
2018-08-18 20:23:58 +01:00
void expression ( ) ;
void function_call ( char * s , int bool )
2018-05-03 01:56:44 +01:00
{
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_expression_list \n No ( was found \n " , " ( " ) ;
2018-05-03 01:56:44 +01:00
int passed = 0 ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
emit_out ( " PUSHR R13 R15 \t # Prevent overwriting in recursion \n " ) ;
emit_out ( " PUSHR R14 R15 \t # Protect the old base pointer \n " ) ;
emit_out ( " COPY R13 R15 \t # Copy new base pointer \n " ) ;
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
emit_out ( " PUSH_edi \t # Prevent overwriting in recursion \n " ) ;
emit_out ( " PUSH_ebp \t # Protect the old base pointer \n " ) ;
emit_out ( " COPY_esp_to_edi \t # Copy new base pointer \n " ) ;
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
emit_out ( " PUSH_RDI \t # Prevent overwriting in recursion \n " ) ;
emit_out ( " PUSH_RBP \t # Protect the old base pointer \n " ) ;
emit_out ( " COPY_RSP_to_RDI \t # Copy new base pointer \n " ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-03-17 00:03:56 +00:00
emit_out ( " {R11} PUSH_ALWAYS \t # Prevent overwriting in recursion \n " ) ;
emit_out ( " {BP} PUSH_ALWAYS \t # Protect the old base pointer \n " ) ;
emit_out ( " '0' SP R11 NO_SHIFT MOVE_ALWAYS \t # Copy new base pointer \n " ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " PUSH_X16 \t # Protect a tmp register we're going to use \n " ) ;
emit_out ( " PUSH_LR \t # Protect the old return pointer (link) \n " ) ;
emit_out ( " PUSH_BP \t # Protect the old base pointer \n " ) ;
emit_out ( " SET_X16_FROM_SP \t # The base pointer to-be \n " ) ;
}
2018-05-03 01:56:44 +01:00
if ( global_token - > s [ 0 ] ! = ' ) ' )
{
2018-08-18 20:23:58 +01:00
expression ( ) ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete function call, recieved EOF instead of ) \n " ) ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " PUSHR R0 R15 \t #_process_expression1 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " PUSH_eax \t #_process_expression1 \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " PUSH_RAX \t #_process_expression1 \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R0 } PUSH_ALWAYS \ t # _process_expression1 \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " PUSH_X0 \t #_process_expression1 \n " ) ;
2018-05-03 01:56:44 +01:00
passed = 1 ;
while ( global_token - > s [ 0 ] = = ' , ' )
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete function call, recieved EOF instead of argument \n " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " PUSHR R0 R15 \t #_process_expression2 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " PUSH_eax \t #_process_expression2 \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " PUSH_RAX \t #_process_expression2 \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R0 } PUSH_ALWAYS \ t # _process_expression2 \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " PUSH_X0 \t #_process_expression2 \n " ) ;
2018-05-03 01:56:44 +01:00
passed = passed + 1 ;
}
}
require_match ( " ERROR in process_expression_list \n No ) was found \n " , " ) " ) ;
2018-07-20 03:33:02 +01:00
if ( TRUE = = bool )
2018-05-03 01:56:44 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
2019-03-09 16:56:16 +00:00
emit_out ( " LOAD R0 R14 " ) ;
2019-02-23 23:33:57 +00:00
emit_out ( s ) ;
2019-03-09 16:56:16 +00:00
emit_out ( " \n MOVE R14 R13 \n " ) ;
2019-02-23 23:33:57 +00:00
emit_out ( " CALL R0 R15 \n " ) ;
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
emit_out ( " LOAD_BASE_ADDRESS_eax % " ) ;
emit_out ( s ) ;
emit_out ( " \n LOAD_INTEGER \n " ) ;
emit_out ( " COPY_edi_to_ebp \n " ) ;
emit_out ( " CALL_eax \n " ) ;
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
emit_out ( " LOAD_BASE_ADDRESS_rax % " ) ;
emit_out ( s ) ;
emit_out ( " \n LOAD_INTEGER \n " ) ;
emit_out ( " COPY_rdi_to_rbp \n " ) ;
emit_out ( " CALL_rax \n " ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
emit_out ( " ! " ) ;
emit_out ( s ) ;
2019-03-23 22:29:19 +00:00
emit_out ( " R0 SUB BP ARITH_ALWAYS \n " ) ;
emit_out ( " !0 R0 LOAD32 R0 MEMORY \n " ) ;
2019-03-17 00:03:56 +00:00
emit_out ( " {LR} PUSH_ALWAYS \t # Protect the old link register \n " ) ;
2019-03-30 13:25:52 +00:00
emit_out ( " '0' R11 BP NO_SHIFT MOVE_ALWAYS \n " ) ;
2019-03-18 02:34:26 +00:00
emit_out ( " '3' R0 CALL_REG_ALWAYS \n " ) ;
2019-03-17 00:03:56 +00:00
emit_out ( " {LR} POP_ALWAYS \t # Prevent overwrite \n " ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " SET_X0_FROM_BP \n " ) ;
emit_out ( " LOAD_W1_AHEAD \n SKIP_32_DATA \n % " ) ;
emit_out ( s ) ;
emit_out ( " \n SUB_X0_X0_X1 \n " ) ;
emit_out ( " DEREF_X0 \n " ) ;
emit_out ( " SET_BP_FROM_X16 \n " ) ;
emit_out ( " SET_X16_FROM_X0 \n " ) ;
emit_out ( " BLR_X16 \n " ) ;
}
2018-05-03 01:56:44 +01:00
}
else
{
2020-02-01 03:43:51 +00:00
if ( ( KNIGHT_NATIVE = = Architecture ) | | ( KNIGHT_POSIX = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
emit_out ( " MOVE R14 R13 \n " ) ;
2019-03-09 20:25:29 +00:00
emit_out ( " LOADR R0 4 \n JUMP 4 \n &FUNCTION_ " ) ;
2019-02-23 23:33:57 +00:00
emit_out ( s ) ;
2019-03-09 20:25:29 +00:00
emit_out ( " \n CALL R0 R15 \n " ) ;
2019-02-23 23:33:57 +00:00
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
emit_out ( " COPY_edi_to_ebp \n " ) ;
emit_out ( " CALL_IMMEDIATE %FUNCTION_ " ) ;
emit_out ( s ) ;
emit_out ( " \n " ) ;
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
emit_out ( " COPY_rdi_to_rbp \n " ) ;
emit_out ( " CALL_IMMEDIATE %FUNCTION_ " ) ;
emit_out ( s ) ;
emit_out ( " \n " ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-03-17 00:03:56 +00:00
emit_out ( " {LR} PUSH_ALWAYS \t # Protect the old link register \n " ) ;
emit_out ( " '0' R11 BP NO_SHIFT MOVE_ALWAYS \n " ) ;
2019-03-10 01:22:29 +00:00
emit_out ( " ^~FUNCTION_ " ) ;
emit_out ( s ) ;
emit_out ( " CALL_ALWAYS \n " ) ;
2019-03-17 00:03:56 +00:00
emit_out ( " {LR} POP_ALWAYS \t # Restore the old link register \n " ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " SET_BP_FROM_X16 \n " ) ;
emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &FUNCTION_ " ) ;
emit_out ( s ) ;
emit_out ( " \n " ) ;
emit_out ( " BLR_X16 \n " ) ;
}
2018-05-03 01:56:44 +01:00
}
for ( ; passed > 0 ; passed = passed - 1 )
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " POPR R1 R15 \t # _process_expression_locals \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " POP_ebx \t # _process_expression_locals \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " POP_RBX \t # _process_expression_locals \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R1 } POP_ALWAYS \ t # _process_expression_locals \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " POP_X1 \t # _process_expression_locals \n " ) ;
2019-02-23 23:33:57 +00:00
}
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
emit_out ( " POPR R14 R15 \t # Restore old base pointer \n " ) ;
emit_out ( " POPR R13 R15 \t # Prevent overwrite \n " ) ;
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
emit_out ( " POP_ebp \t # Restore old base pointer \n " ) ;
emit_out ( " POP_edi \t # Prevent overwrite \n " ) ;
2018-05-03 01:56:44 +01:00
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
emit_out ( " POP_RBP \t # Restore old base pointer \n " ) ;
emit_out ( " POP_RDI \t # Prevent overwrite \n " ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-03-17 00:03:56 +00:00
emit_out ( " {BP} POP_ALWAYS \t # Restore old base pointer \n " ) ;
emit_out ( " {R11} POP_ALWAYS \t # Prevent overwrite \n " ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " POP_BP \t # Restore the old base pointer \n " ) ;
emit_out ( " POP_LR \t # Restore the old return pointer (link) \n " ) ;
emit_out ( " POP_X16 \t # Restore a register we used as tmp \n " ) ;
}
2018-05-03 01:56:44 +01:00
}
2018-08-18 20:23:58 +01:00
void constant_load ( struct token_list * a )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOADI R0 " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax % " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax % " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n % " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n % " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( a - > arguments - > s ) ;
emit_out ( " \n " ) ;
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void variable_load ( struct token_list * a )
2018-07-20 03:33:02 +01:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete variable load recieved \n " ) ;
2020-12-28 02:51:46 +00:00
if ( ( match ( " FUNCTION " , a - > type - > name ) | | match ( " FUNCTION* " , a - > type - > name ) ) & & match ( " ( " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
function_call ( numerate_number ( a - > depth ) , TRUE ) ;
return ;
2018-01-21 03:56:50 +00:00
}
2018-07-20 03:33:02 +01:00
current_target = a - > type ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " ADDI R0 R14 " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_BASE_ADDRESS_eax % " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_BASE_ADDRESS_rax % " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ! " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " SET_X0_FROM_BP \n LOAD_W1_AHEAD \n SKIP_32_DATA \n % " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( numerate_number ( a - > depth ) ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " R0 SUB BP ARITH_ALWAYS " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n SUB_X0_X0_X1 \n " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " \n " ) ;
2019-03-10 17:07:19 +00:00
2018-10-17 21:08:04 +01:00
if ( TRUE = = Address_of ) return ;
2018-08-21 01:41:37 +01:00
if ( match ( " = " , global_token - > s ) ) return ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOAD R0 R0 0 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R0 MEMORY \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " DEREF_X0 \n " ) ;
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void function_load ( struct token_list * a )
2018-07-20 03:33:02 +01:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete function load \n " ) ;
2018-08-18 20:23:58 +01:00
if ( match ( " ( " , global_token - > s ) )
{
function_call ( a - > s , FALSE ) ;
return ;
}
2018-05-03 01:56:44 +01:00
2020-02-01 03:43:51 +00:00
if ( ( KNIGHT_NATIVE = = Architecture ) | | ( KNIGHT_POSIX = = Architecture ) ) emit_out ( " LOADR R0 4 \n JUMP 4 \n &FUNCTION_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax &FUNCTION_ " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax &FUNCTION_ " ) ;
2019-03-18 02:34:26 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n &FUNCTION_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n &FUNCTION_ " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( a - > s ) ;
emit_out ( " \n " ) ;
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void global_load ( struct token_list * a )
2018-07-20 03:33:02 +01:00
{
current_target = a - > type ;
2020-02-01 03:43:51 +00:00
if ( ( KNIGHT_NATIVE = = Architecture ) | | ( KNIGHT_POSIX = = Architecture ) ) emit_out ( " LOADR R0 4 \n JUMP 4 \n &GLOBAL_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax &GLOBAL_ " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax &GLOBAL_ " ) ;
2019-03-30 13:25:52 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n &GLOBAL_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n &GLOBAL_ " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( a - > s ) ;
emit_out ( " \n " ) ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " unterminated global load \n " ) ;
2019-02-23 23:33:57 +00:00
if ( ! match ( " = " , global_token - > s ) )
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOAD R0 R0 0 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-03-30 13:25:52 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R0 MEMORY \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " DEREF_X0 \n " ) ;
2019-02-23 23:33:57 +00:00
}
2018-01-21 03:56:50 +00:00
}
/*
* primary - expr :
2018-07-20 03:33:02 +01:00
* FAILURE
* " String "
* ' Char '
* [ 0 - 9 ] *
* [ a - z , A - Z ] *
* ( expression )
2018-01-21 03:56:50 +00:00
*/
2018-07-20 03:33:02 +01:00
2018-08-18 20:23:58 +01:00
void primary_expr_failure ( )
2018-01-21 03:56:50 +00:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " hit EOF when expecting primary expression \n " ) ;
2018-08-27 02:15:32 +01:00
line_error ( ) ;
2019-10-23 20:04:14 +01:00
file_print ( " Received " , stderr ) ;
2018-07-20 03:33:02 +01:00
file_print ( global_token - > s , stderr ) ;
file_print ( " in primary_expr \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void primary_expr_string ( )
2018-07-20 03:33:02 +01:00
{
char * number_string = numerate_number ( current_count ) ;
2018-08-21 01:41:37 +01:00
current_count = current_count + 1 ;
2020-02-01 03:43:51 +00:00
if ( ( KNIGHT_NATIVE = = Architecture ) | | ( KNIGHT_POSIX = = Architecture ) ) emit_out ( " LOADR R0 4 \n JUMP 4 \n &STRING_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax &STRING_ " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax &STRING_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n &STRING_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n &STRING_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2018-07-20 03:33:02 +01:00
/* The target */
strings_list = emit ( " :STRING_ " , strings_list ) ;
strings_list = uniqueID ( function - > s , strings_list , number_string ) ;
2020-12-31 14:53:05 +00:00
/* catch case of just "foo" from segfaulting */
require ( NULL ! = global_token - > next , " a string by itself is not valid C \n " ) ;
2018-07-20 03:33:02 +01:00
/* Parse the string */
2020-11-15 23:58:25 +00:00
if ( ' " ' ! = global_token - > next - > s [ 0 ] )
{
strings_list = emit ( parse_string ( global_token - > s ) , strings_list ) ;
global_token = global_token - > next ;
}
else
{
char * s = calloc ( MAX_STRING , sizeof ( char ) ) ;
/* prefix leading string */
s [ 0 ] = ' " ' ;
int i = 1 ;
int j ;
while ( ' " ' = = global_token - > s [ 0 ] )
{
/* Step past the leading '"' */
j = 1 ;
/* Copy the rest of the string as is */
while ( 0 ! = global_token - > s [ j ] )
{
require ( i < MAX_STRING , " concat string exceeded max string length \n " ) ;
s [ i ] = global_token - > s [ j ] ;
i = i + 1 ;
j = j + 1 ;
}
/* Move on to the next token */
global_token = global_token - > next ;
require ( NULL ! = global_token , " multi-string null is not valid C \n " ) ;
}
/* Now use it */
strings_list = emit ( parse_string ( s ) , strings_list ) ;
}
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void primary_expr_char ( )
2018-07-20 03:33:02 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOADI R0 " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax % " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax % " ) ;
2019-03-18 02:34:26 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ! " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n % " ) ;
2018-08-21 01:41:37 +01:00
emit_out ( numerate_number ( escape_lookup ( global_token - > s + 1 ) ) ) ;
2019-03-18 02:34:26 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " R0 LOADI8_ALWAYS " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " \n " ) ;
2018-07-20 03:33:02 +01:00
global_token = global_token - > next ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void primary_expr_number ( )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-24 22:46:05 +00:00
{
2020-10-17 18:50:25 +01:00
int size = fixup_int32 ( numerate_string ( global_token - > s ) ) ;
2020-02-01 03:43:51 +00:00
if ( ( 32767 > size ) & & ( size > - 32768 ) )
2019-02-24 22:46:05 +00:00
{
emit_out ( " LOADI R0 " ) ;
emit_out ( global_token - > s ) ;
}
else
{
emit_out ( " LOADR R0 4 \n JUMP 4 \n ' " ) ;
2019-04-19 22:43:59 +01:00
emit_out ( number_to_hex ( size , register_size ) ) ;
2019-04-18 01:19:17 +01:00
emit_out ( " ' " ) ;
2019-02-24 22:46:05 +00:00
}
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-24 22:46:05 +00:00
{
emit_out ( " LOAD_IMMEDIATE_eax % " ) ;
emit_out ( global_token - > s ) ;
2019-04-18 01:19:17 +01:00
}
else if ( AMD64 = = Architecture )
{
emit_out ( " LOAD_IMMEDIATE_rax % " ) ;
emit_out ( global_token - > s ) ;
2019-02-24 22:46:05 +00:00
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-03-17 00:03:56 +00:00
emit_out ( " !0 R0 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n % " ) ;
2019-03-10 01:22:29 +00:00
emit_out ( global_token - > s ) ;
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n % " ) ;
emit_out ( global_token - > s ) ;
}
2019-04-18 01:19:17 +01:00
emit_out ( " \n " ) ;
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2018-01-25 01:00:22 +00:00
}
2018-08-18 20:23:58 +01:00
void primary_expr_variable ( )
2018-07-20 03:33:02 +01:00
{
char * s = global_token - > s ;
global_token = global_token - > next ;
struct token_list * a = sym_lookup ( s , global_constant_list ) ;
2018-08-18 20:23:58 +01:00
if ( NULL ! = a )
{
constant_load ( a ) ;
return ;
}
2018-07-20 03:33:02 +01:00
a = sym_lookup ( s , function - > locals ) ;
2018-08-18 20:23:58 +01:00
if ( NULL ! = a )
{
variable_load ( a ) ;
return ;
}
2018-07-20 03:33:02 +01:00
a = sym_lookup ( s , function - > arguments ) ;
2018-08-18 20:23:58 +01:00
if ( NULL ! = a )
{
variable_load ( a ) ;
return ;
}
2018-07-20 03:33:02 +01:00
a = sym_lookup ( s , global_function_list ) ;
2018-08-18 20:23:58 +01:00
if ( NULL ! = a )
{
function_load ( a ) ;
return ;
}
2018-07-20 03:33:02 +01:00
a = sym_lookup ( s , global_symbol_list ) ;
2018-08-18 20:23:58 +01:00
if ( NULL ! = a )
{
global_load ( a ) ;
return ;
}
2018-07-20 03:33:02 +01:00
2018-08-27 02:15:32 +01:00
line_error ( ) ;
2018-07-20 03:33:02 +01:00
file_print ( s , stderr ) ;
file_print ( " is not a defined symbol \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
}
2018-08-18 20:23:58 +01:00
void primary_expr ( ) ;
2018-04-24 02:35:27 +01:00
struct type * promote_type ( struct type * a , struct type * b )
{
2020-12-31 14:53:05 +00:00
require ( NULL ! = b , " impossible case 1 in promote_type \n " ) ;
require ( NULL ! = a , " impossible case 2 in promote_type \n " ) ;
if ( a = = b ) return a ;
2018-04-24 02:35:27 +01:00
struct type * i ;
for ( i = global_types ; NULL ! = i ; i = i - > next )
{
2018-08-26 21:34:31 +01:00
if ( a - > name = = i - > name ) break ;
if ( b - > name = = i - > name ) break ;
if ( a - > name = = i - > indirect - > name ) break ;
if ( b - > name = = i - > indirect - > name ) break ;
2020-12-31 14:53:05 +00:00
if ( a - > name = = i - > indirect - > indirect - > name ) break ;
if ( b - > name = = i - > indirect - > indirect - > name ) break ;
2018-04-24 02:35:27 +01:00
}
2020-12-31 14:53:05 +00:00
require ( NULL ! = i , " impossible case 3 in promote_type \n " ) ;
2018-08-26 21:34:31 +01:00
return i ;
2018-04-24 02:35:27 +01:00
}
2018-08-18 20:23:58 +01:00
void common_recursion ( FUNCTION f )
2018-01-25 01:00:22 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " PUSHR R0 R15 \t #_common_recursion \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " PUSH_eax \t #_common_recursion \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " PUSH_RAX \t #_common_recursion \n " ) ;
2019-03-10 15:24:13 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R0 } PUSH_ALWAYS \ t # _common_recursion \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " PUSH_X0 \t #_common_recursion \n " ) ;
2019-02-23 23:33:57 +00:00
2019-06-20 02:43:34 +01:00
struct type * last_type = current_target ;
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF in common_recursion \n " ) ;
2018-08-18 20:23:58 +01:00
f ( ) ;
2018-04-24 02:35:27 +01:00
current_target = promote_type ( current_target , last_type ) ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " POPR R1 R15 \t # _common_recursion \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " POP_ebx \t # _common_recursion \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " POP_RBX \t # _common_recursion \n " ) ;
2019-03-10 15:24:13 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R1 } POP_ALWAYS \ t # _common_recursion \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " POP_X1 \t # _common_recursion \n " ) ;
2018-01-21 03:56:50 +00:00
}
2019-10-27 16:55:07 +00:00
void general_recursion ( FUNCTION f , char * s , char * name , FUNCTION iterate )
2018-07-20 03:33:02 +01:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF in general_recursion \n " ) ;
2018-07-20 03:33:02 +01:00
if ( match ( name , global_token - > s ) )
{
2018-08-18 20:23:58 +01:00
common_recursion ( f ) ;
emit_out ( s ) ;
iterate ( ) ;
2018-07-20 03:33:02 +01:00
}
}
2019-10-27 16:55:07 +00:00
void arithmetic_recursion ( FUNCTION f , char * s1 , char * s2 , char * name , FUNCTION iterate )
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF in arithmetic_recursion \n " ) ;
2019-10-27 16:55:07 +00:00
if ( match ( name , global_token - > s ) )
{
common_recursion ( f ) ;
if ( NULL = = current_target )
{
2020-12-15 12:24:07 +00:00
emit_out ( s1 ) ;
2019-10-27 16:55:07 +00:00
}
else if ( current_target - > is_signed )
{
emit_out ( s1 ) ;
}
else
{
emit_out ( s2 ) ;
}
iterate ( ) ;
}
}
2018-01-21 03:56:50 +00:00
int ceil_log2 ( int a )
{
int result = 0 ;
if ( ( a & ( a - 1 ) ) = = 0 )
{
result = - 1 ;
}
while ( a > 0 )
{
result = result + 1 ;
a = a > > 1 ;
}
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) return ( result > > 1 ) ;
2018-01-21 03:56:50 +00:00
return result ;
}
/*
* postfix - expr :
* primary - expr
* postfix - expr [ expression ]
* postfix - expr ( expression - list - opt )
* postfix - expr - > member
*/
2018-08-26 21:34:31 +01:00
struct type * lookup_member ( struct type * parent , char * name ) ;
2018-08-18 20:23:58 +01:00
void postfix_expr_arrow ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
emit_out ( " # looking up offset \n " ) ;
2018-07-20 03:33:02 +01:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " naked -> not allowed \n " ) ;
2018-08-26 21:34:31 +01:00
struct type * i = lookup_member ( current_target , global_token - > s ) ;
current_target = i - > type ;
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Unterminated -> expression not allowed \n " ) ;
2018-08-26 21:34:31 +01:00
2018-07-20 03:33:02 +01:00
if ( 0 ! = i - > offset )
{
2018-08-18 20:23:58 +01:00
emit_out ( " # -> offset calculation \n " ) ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
emit_out ( " ADDUI R0 R0 " ) ;
emit_out ( numerate_number ( i - > offset ) ) ;
emit_out ( " \n " ) ;
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
emit_out ( " LOAD_IMMEDIATE_ebx % " ) ;
emit_out ( numerate_number ( i - > offset ) ) ;
emit_out ( " \n ADD_ebx_to_eax \n " ) ;
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
emit_out ( " LOAD_IMMEDIATE_rbx % " ) ;
emit_out ( numerate_number ( i - > offset ) ) ;
emit_out ( " \n ADD_rbx_to_rax \n " ) ;
}
2019-03-17 03:27:52 +00:00
else if ( ARMV7L = = Architecture )
{
emit_out ( " !0 R1 LOAD32 R15 MEMORY \n ~0 JUMP_ALWAYS \n % " ) ;
emit_out ( numerate_number ( i - > offset ) ) ;
emit_out ( " \n '0' R0 R0 ADD R1 ARITH2_ALWAYS \n " ) ;
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
emit_out ( " LOAD_W1_AHEAD \n SKIP_32_DATA \n % " ) ;
emit_out ( numerate_number ( i - > offset ) ) ;
emit_out ( " \n ADD_X0_X1_X0 \n " ) ;
}
2018-07-20 03:33:02 +01:00
}
2018-08-26 21:34:31 +01:00
2019-04-19 22:43:59 +01:00
if ( ( ! match ( " = " , global_token - > s ) & & ( register_size > = i - > size ) ) )
2018-07-20 03:33:02 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOAD R0 R0 0 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_INTEGER \n " ) ;
2019-03-17 03:27:52 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOAD32 R0 MEMORY \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " DEREF_X0 \n " ) ;
2018-07-20 03:33:02 +01:00
}
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void postfix_expr_array ( )
2018-07-20 03:33:02 +01:00
{
struct type * array = current_target ;
2018-08-18 20:23:58 +01:00
common_recursion ( expression ) ;
2018-07-20 03:33:02 +01:00
current_target = array ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = current_target , " Arrays only apply to variables \n " ) ;
2019-02-23 23:33:57 +00:00
char * assign ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) assign = " LOAD R0 R0 0 \n " ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) assign = " LOAD_INTEGER \n " ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) assign = " LOAD_INTEGER \n " ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) assign = " !0 R0 LOAD32 R0 MEMORY \n " ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) assign = " DEREF_X0 \n " ;
2018-01-21 03:56:50 +00:00
2018-07-20 03:33:02 +01:00
/* Add support for Ints */
2019-02-23 23:33:57 +00:00
if ( match ( " char* " , current_target - > name ) )
2018-07-20 03:33:02 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) assign = " LOAD8 R0 R0 0 \n " ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) assign = " LOAD_BYTE \n " ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) assign = " LOAD_BYTE \n " ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) assign = " !0 R0 LOAD8 R0 MEMORY \n " ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) assign = " DEREF_X0_BYTE \n " ;
2018-07-20 03:33:02 +01:00
}
else
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " SALI R0 " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " SAL_eax_Immediate8 ! " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " SAL_rax_Immediate8 ! " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '0' R0 R0 ' " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W2_AHEAD \n SKIP_32_DATA \n % " ) ;
2019-02-23 23:33:57 +00:00
2018-08-26 21:34:31 +01:00
emit_out ( numerate_number ( ceil_log2 ( current_target - > indirect - > size ) ) ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " ' MOVE_ALWAYS " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n LSHIFT_X0_X0_X2 " ) ;
2018-08-26 21:34:31 +01:00
emit_out ( " \n " ) ;
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " ADD R0 R0 R1 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " ADD_ebx_to_eax \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " ADD_rbx_to_rax \n " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '0' R0 R0 ADD R1 ARITH2_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " ADD_X0_X1_X0 \n " ) ;
2019-02-23 23:33:57 +00:00
2018-07-20 03:33:02 +01:00
require_match ( " ERROR in postfix_expr \n Missing ] \n " , " ] " ) ;
if ( match ( " = " , global_token - > s ) )
{
assign = " " ;
2018-01-21 03:56:50 +00:00
}
2018-07-20 03:33:02 +01:00
2018-08-18 20:23:58 +01:00
emit_out ( assign ) ;
2018-01-21 03:56:50 +00:00
}
2018-01-21 19:42:09 +00:00
/*
* unary - expr :
* postfix - expr
* - postfix - expr
* ! postfix - expr
2018-01-25 01:00:22 +00:00
* sizeof ( type )
2018-01-21 19:42:09 +00:00
*/
2018-01-25 01:00:22 +00:00
struct type * type_name ( ) ;
2018-08-18 20:23:58 +01:00
void unary_expr_sizeof ( )
2018-01-21 19:42:09 +00:00
{
2018-07-20 03:33:02 +01:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF when starting sizeof \n " ) ;
2018-07-20 03:33:02 +01:00
require_match ( " ERROR in unary_expr \n Missing ( \n " , " ( " ) ;
struct type * a = type_name ( ) ;
require_match ( " ERROR in unary_expr \n Missing ) \n " , " ) " ) ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " LOADUI R0 " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax % " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax % " ) ;
2019-03-17 03:27:52 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ! " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W0_AHEAD \n SKIP_32_DATA \n % " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( numerate_number ( a - > size ) ) ;
2019-03-17 03:27:52 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " R0 LOADI8_ALWAYS " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " \n " ) ;
2018-07-20 03:33:02 +01:00
}
2018-08-18 20:23:58 +01:00
void postfix_expr_stub ( )
2018-07-20 03:33:02 +01:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Unexpected EOF, improperly terminated primary expression \n " ) ;
2018-07-20 03:33:02 +01:00
if ( match ( " [ " , global_token - > s ) )
2018-01-21 19:42:09 +00:00
{
2018-08-18 20:23:58 +01:00
postfix_expr_array ( ) ;
postfix_expr_stub ( ) ;
2018-01-21 19:42:09 +00:00
}
2018-07-20 03:33:02 +01:00
if ( match ( " -> " , global_token - > s ) )
2018-01-21 19:42:09 +00:00
{
2018-08-18 20:23:58 +01:00
postfix_expr_arrow ( ) ;
postfix_expr_stub ( ) ;
2018-01-21 19:42:09 +00:00
}
2018-07-20 03:33:02 +01:00
}
2018-01-21 19:42:09 +00:00
2018-08-18 20:23:58 +01:00
void postfix_expr ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
primary_expr ( ) ;
postfix_expr_stub ( ) ;
2018-01-21 19:42:09 +00:00
}
2018-01-21 03:56:50 +00:00
/*
* additive - expr :
* postfix - expr
2018-01-25 01:00:22 +00:00
* additive - expr * postfix - expr
* additive - expr / postfix - expr
* additive - expr % postfix - expr
2018-01-21 03:56:50 +00:00
* additive - expr + postfix - expr
* additive - expr - postfix - expr
2018-07-20 03:33:02 +01:00
* additive - expr < < postfix - expr
* additive - expr > > postfix - expr
2018-01-21 03:56:50 +00:00
*/
2018-08-18 20:23:58 +01:00
void additive_expr_stub ( )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
2019-10-27 16:55:07 +00:00
arithmetic_recursion ( postfix_expr , " ADD R0 R1 R0 \n " , " ADDU R0 R1 R0 \n " , " + " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SUB R0 R1 R0 \n " , " SUBU R0 R1 R0 \n " , " - " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " MUL R0 R1 R0 \n " , " MULU R0 R1 R0 \n " , " * " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " DIV R0 R1 R0 \n " , " DIVU R0 R1 R0 \n " , " / " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " MOD R0 R1 R0 \n " , " MODU R0 R1 R0 \n " , " % " , additive_expr_stub ) ;
2020-10-17 03:07:06 +01:00
arithmetic_recursion ( postfix_expr , " SAL R0 R1 R0 \n " , " SL0 R0 R1 R0 \n " , " << " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SAR R0 R1 R0 \n " , " SR0 R0 R1 R0 \n " , " >> " , additive_expr_stub ) ;
2019-02-23 23:33:57 +00:00
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
2019-10-27 16:55:07 +00:00
arithmetic_recursion ( postfix_expr , " ADD_ebx_to_eax \n " , " ADD_ebx_to_eax \n " , " + " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SUBTRACT_eax_from_ebx_into_ebx \n MOVE_ebx_to_eax \n " , " SUBTRACT_eax_from_ebx_into_ebx \n MOVE_ebx_to_eax \n " , " - " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " MULTIPLYS_eax_by_ebx_into_eax \n " , " MULTIPLY_eax_by_ebx_into_eax \n " , " * " , additive_expr_stub ) ;
2019-11-29 17:55:55 +00:00
arithmetic_recursion ( postfix_expr , " XCHG_eax_ebx \n CDTQ \n DIVIDES_eax_by_ebx_into_eax \n " , " XCHG_eax_ebx \n LOAD_IMMEDIATE_edx %0 \n DIVIDE_eax_by_ebx_into_eax \n " , " / " , additive_expr_stub ) ;
2021-01-01 21:39:27 +00:00
arithmetic_recursion ( postfix_expr , " XCHG_eax_ebx \n CDTQ \n MODULUSS_eax_from_ebx_into_ebx \n MOVE_edx_to_eax \n " , " XCHG_eax_ebx \n LOAD_IMMEDIATE_edx %0 \n MODULUS_eax_from_ebx_into_ebx \n MOVE_edx_to_eax \n " , " % " , additive_expr_stub ) ;
2020-10-17 03:07:06 +01:00
arithmetic_recursion ( postfix_expr , " COPY_eax_to_ecx \n COPY_ebx_to_eax \n SAL_eax_cl \n " , " COPY_eax_to_ecx \n COPY_ebx_to_eax \n SHL_eax_cl \n " , " << " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " COPY_eax_to_ecx \n COPY_ebx_to_eax \n SAR_eax_cl \n " , " COPY_eax_to_ecx \n COPY_ebx_to_eax \n SHR_eax_cl \n " , " >> " , additive_expr_stub ) ;
2019-02-23 23:33:57 +00:00
}
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture )
{
2019-10-27 16:55:07 +00:00
arithmetic_recursion ( postfix_expr , " ADD_rbx_to_rax \n " , " ADD_rbx_to_rax \n " , " + " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SUBTRACT_rax_from_rbx_into_rbx \n MOVE_rbx_to_rax \n " , " SUBTRACT_rax_from_rbx_into_rbx \n MOVE_rbx_to_rax \n " , " - " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " MULTIPLYS_rax_by_rbx_into_rax \n " , " MULTIPLY_rax_by_rbx_into_rax \n " , " * " , additive_expr_stub ) ;
2019-11-29 17:55:55 +00:00
arithmetic_recursion ( postfix_expr , " XCHG_rax_rbx \n CQTO \n DIVIDES_rax_by_rbx_into_rax \n " , " XCHG_rax_rbx \n LOAD_IMMEDIATE_rdx %0 \n DIVIDE_rax_by_rbx_into_rax \n " , " / " , additive_expr_stub ) ;
2021-01-01 21:39:27 +00:00
arithmetic_recursion ( postfix_expr , " XCHG_rax_rbx \n CQTO \n MODULUSS_rax_from_rbx_into_rbx \n MOVE_rdx_to_rax \n " , " XCHG_rax_rbx \n LOAD_IMMEDIATE_rdx %0 \n MODULUS_rax_from_rbx_into_rbx \n MOVE_rdx_to_rax \n " , " % " , additive_expr_stub ) ;
2020-10-17 03:07:06 +01:00
arithmetic_recursion ( postfix_expr , " COPY_rax_to_rcx \n COPY_rbx_to_rax \n SAL_rax_cl \n " , " COPY_rax_to_rcx \n COPY_rbx_to_rax \n SHL_rax_cl \n " , " << " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " COPY_rax_to_rcx \n COPY_rbx_to_rax \n SAR_rax_cl \n " , " COPY_rax_to_rcx \n COPY_rbx_to_rax \n SHR_rax_cl \n " , " >> " , additive_expr_stub ) ;
2019-04-19 22:43:59 +01:00
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-10-27 16:55:07 +00:00
arithmetic_recursion ( postfix_expr , " '0' R0 R0 ADD R1 ARITH2_ALWAYS \n " , " '0' R0 R0 ADD R1 ARITH2_ALWAYS \n " , " + " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " '0' R0 R0 SUB R1 ARITH2_ALWAYS \n " , " '0' R0 R0 SUB R1 ARITH2_ALWAYS \n " , " - " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " '9' R0 '0' R1 MULS R0 ARITH2_ALWAYS \n " , " '9' R0 '0' R1 MUL R0 ARITH2_ALWAYS \n " , " * " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " {LR} PUSH_ALWAYS \n ^~divides CALL_ALWAYS \n {LR} POP_ALWAYS \n " , " {LR} PUSH_ALWAYS \n ^~divide CALL_ALWAYS \n {LR} POP_ALWAYS \n " , " / " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " {LR} PUSH_ALWAYS \n ^~moduluss CALL_ALWAYS \n {LR} POP_ALWAYS \n " , " {LR} PUSH_ALWAYS \n ^~modulus CALL_ALWAYS \n {LR} POP_ALWAYS \n " , " % " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " LEFT R1 R0 R0 SHIFT AUX_ALWAYS \n " , " LEFT R1 R0 R0 SHIFT AUX_ALWAYS \n " , " << " , additive_expr_stub ) ;
2020-10-17 03:07:06 +01:00
arithmetic_recursion ( postfix_expr , " ARITH_RIGHT R1 R0 R0 SHIFT AUX_ALWAYS \n " , " RIGHT R1 R0 R0 SHIFT AUX_ALWAYS \n " , " >> " , additive_expr_stub ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
general_recursion ( postfix_expr , " ADD_X0_X1_X0 \n " , " + " , additive_expr_stub ) ;
general_recursion ( postfix_expr , " SUB_X0_X1_X0 \n " , " - " , additive_expr_stub ) ;
general_recursion ( postfix_expr , " MUL_X0_X1_X0 \n " , " * " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SDIV_X0_X1_X0 \n " , " UDIV_X0_X1_X0 \n " , " / " , additive_expr_stub ) ;
arithmetic_recursion ( postfix_expr , " SDIV_X2_X1_X0 \n MSUB_X0_X0_X2_X1 \n " , " UDIV_X2_X1_X0 \n MSUB_X0_X0_X2_X1 \n " , " % " , additive_expr_stub ) ;
general_recursion ( postfix_expr , " LSHIFT_X0_X1_X0 \n " , " << " , additive_expr_stub ) ;
2020-12-04 19:35:30 +00:00
arithmetic_recursion ( postfix_expr , " ARITH_RSHIFT_X0_X1_X0 \n " , " LOGICAL_RSHIFT_X0_X1_X0 \n " , " >> " , additive_expr_stub ) ;
2020-02-01 20:23:49 +00:00
}
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void additive_expr ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
postfix_expr ( ) ;
additive_expr_stub ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-07-20 03:33:02 +01:00
2018-01-21 03:56:50 +00:00
/*
* relational - expr :
2018-07-20 03:33:02 +01:00
* additive_expr
* relational - expr < additive_expr
* relational - expr < = additive_expr
* relational - expr > = additive_expr
* relational - expr > additive_expr
2018-01-21 03:56:50 +00:00
*/
2018-07-20 03:33:02 +01:00
2018-08-18 20:23:58 +01:00
void relational_expr_stub ( )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
2020-12-15 12:24:07 +00:00
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.L R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.L R0 R0 1 \n " , " < " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.LE R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.LE R0 R0 1 \n " , " <= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.GE R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.GE R0 R0 1 \n " , " >= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.G R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.G R0 R0 1 \n " , " > " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.E R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.E R0 R0 1 \n " , " == " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP R0 R1 R0 \n SET.NE R0 R0 1 \n " , " CMPU R0 R1 R0 \n SET.NE R0 R0 1 \n " , " != " , relational_expr_stub ) ;
2019-02-23 23:33:57 +00:00
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
2020-12-15 22:46:45 +00:00
arithmetic_recursion ( additive_expr , " CMP \n SETL \n MOVEZBL \n " , " CMP \n SETB \n MOVEZBL \n " , " < " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETLE \n MOVEZBL \n " , " CMP \n SETBE \n MOVEZBL \n " , " <= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETGE \n MOVEZBL \n " , " CMP \n SETAE \n MOVEZBL \n " , " >= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETG \n MOVEZBL \n " , " CMP \n SETA \n MOVEZBL \n " , " > " , relational_expr_stub ) ;
2019-02-23 23:33:57 +00:00
general_recursion ( additive_expr , " CMP \n SETE \n MOVEZBL \n " , " == " , relational_expr_stub ) ;
general_recursion ( additive_expr , " CMP \n SETNE \n MOVEZBL \n " , " != " , relational_expr_stub ) ;
}
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture )
{
2020-12-16 01:28:04 +00:00
arithmetic_recursion ( additive_expr , " CMP \n SETL \n MOVEZX \n " , " CMP \n SETB \n MOVEZX \n " , " < " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETLE \n MOVEZX \n " , " CMP \n SETBE \n MOVEZX \n " , " <= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETGE \n MOVEZX \n " , " CMP \n SETAE \n MOVEZX \n " , " >= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP \n SETG \n MOVEZX \n " , " CMP \n SETA \n MOVEZX \n " , " > " , relational_expr_stub ) ;
2019-04-18 01:19:17 +01:00
general_recursion ( additive_expr , " CMP \n SETE \n MOVEZX \n " , " == " , relational_expr_stub ) ;
general_recursion ( additive_expr , " CMP \n SETNE \n MOVEZX \n " , " != " , relational_expr_stub ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2020-12-16 02:09:26 +00:00
arithmetic_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_L \n " , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_LO \n " , " < " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_LE \n " , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_LS \n " , " <= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_GE \n " , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_HS \n " , " >= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_G \n " , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_HI \n " , " > " , relational_expr_stub ) ;
2019-03-17 00:03:56 +00:00
general_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_EQUAL \n " , " == " , relational_expr_stub ) ;
general_recursion ( additive_expr , " '0' R0 CMP R1 AUX_ALWAYS \n !0 R0 LOADI8_ALWAYS \n !1 R0 LOADI8_NE \n " , " != " , relational_expr_stub ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
2020-12-17 00:01:17 +00:00
arithmetic_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_LT \n SET_X0_TO_0 \n " , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_LO \n SET_X0_TO_0 \n " , " < " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_LE \n SET_X0_TO_0 \n " , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_LS \n SET_X0_TO_0 \n " , " <= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_GE \n SET_X0_TO_0 \n " , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_HS \n SET_X0_TO_0 \n " , " >= " , relational_expr_stub ) ;
arithmetic_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_GT \n SET_X0_TO_0 \n " , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_HI \n SET_X0_TO_0 \n " , " > " , relational_expr_stub ) ;
2020-02-01 20:23:49 +00:00
general_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_EQ \n SET_X0_TO_0 \n " , " == " , relational_expr_stub ) ;
general_recursion ( additive_expr , " CMP_X1_X0 \n SET_X0_TO_1 \n SKIP_INST_NE \n SET_X0_TO_0 \n " , " != " , relational_expr_stub ) ;
}
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
void relational_expr ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
additive_expr ( ) ;
relational_expr_stub ( ) ;
2018-01-21 03:56:50 +00:00
}
/*
2018-07-20 03:33:02 +01:00
* bitwise - expr :
2018-01-21 03:56:50 +00:00
* relational - expr
2018-07-20 03:33:02 +01:00
* bitwise - expr & bitwise - expr
* bitwise - expr & & bitwise - expr
* bitwise - expr | bitwise - expr
* bitwise - expr | | bitwise - expr
* bitwise - expr ^ bitwise - expr
2018-01-21 03:56:50 +00:00
*/
2018-08-18 20:23:58 +01:00
void bitwise_expr_stub ( )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) )
2019-02-23 23:33:57 +00:00
{
general_recursion ( relational_expr , " AND R0 R0 R1 \n " , " & " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " AND R0 R0 R1 \n " , " && " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR R0 R0 R1 \n " , " | " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR R0 R0 R1 \n " , " || " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " XOR R0 R0 R1 \n " , " ^ " , bitwise_expr_stub ) ;
}
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture )
2019-02-23 23:33:57 +00:00
{
general_recursion ( relational_expr , " AND_eax_ebx \n " , " & " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " AND_eax_ebx \n " , " && " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_eax_ebx \n " , " | " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_eax_ebx \n " , " || " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " XOR_ebx_eax_into_eax \n " , " ^ " , bitwise_expr_stub ) ;
}
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture )
{
general_recursion ( relational_expr , " AND_rax_rbx \n " , " & " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " AND_rax_rbx \n " , " && " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_rax_rbx \n " , " | " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_rax_rbx \n " , " || " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " XOR_rbx_rax_into_rax \n " , " ^ " , bitwise_expr_stub ) ;
}
2019-03-10 01:22:29 +00:00
else if ( ARMV7L = = Architecture )
{
2019-03-17 00:03:56 +00:00
general_recursion ( relational_expr , " NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS \n " , " & " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS \n " , " && " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " NO_SHIFT R0 R0 OR R1 AUX_ALWAYS \n " , " | " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " NO_SHIFT R0 R0 OR R1 AUX_ALWAYS \n " , " || " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " '0' R0 R0 XOR R1 ARITH2_ALWAYS \n " , " ^ " , bitwise_expr_stub ) ;
2019-03-10 01:22:29 +00:00
}
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture )
{
general_recursion ( relational_expr , " AND_X0_X1_X0 \n " , " & " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " AND_X0_X1_X0 \n " , " && " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_X0_X1_X0 \n " , " | " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " OR_X0_X1_X0 \n " , " || " , bitwise_expr_stub ) ;
general_recursion ( relational_expr , " XOR_X0_X1_X0 \n " , " ^ " , bitwise_expr_stub ) ;
}
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void bitwise_expr ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
relational_expr ( ) ;
bitwise_expr_stub ( ) ;
2018-01-21 03:56:50 +00:00
}
/*
* expression :
* bitwise - or - expr
* bitwise - or - expr = expression
*/
2018-08-18 20:23:58 +01:00
void primary_expr ( )
2018-07-20 03:33:02 +01:00
{
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF where primary expression expected \n " ) ;
2018-10-17 21:08:04 +01:00
if ( match ( " & " , global_token - > s ) )
{
Address_of = TRUE ;
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF after & where primary expression expected \n " ) ;
2018-10-17 21:08:04 +01:00
}
else
{
Address_of = FALSE ;
}
2018-08-18 20:23:58 +01:00
if ( match ( " sizeof " , global_token - > s ) ) unary_expr_sizeof ( ) ;
2018-08-17 09:55:56 +01:00
else if ( ' - ' = = global_token - > s [ 0 ] )
{
2019-02-26 23:04:49 +00:00
if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax %0 \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax %0 \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 R0 LOADI8_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " SET_X0_TO_0 \n " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
common_recursion ( primary_expr ) ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " NEG R0 R0 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " SUBTRACT_eax_from_ebx_into_ebx \n MOVE_ebx_to_eax \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " SUBTRACT_rax_from_rbx_into_rbx \n MOVE_rbx_to_rax \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '0' R0 R0 SUB R1 ARITH2_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " SUB_X0_X1_X0 \n " ) ;
2018-08-17 09:55:56 +01:00
}
else if ( ' ! ' = = global_token - > s [ 0 ] )
{
2019-02-26 23:04:49 +00:00
if ( X86 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_eax %1 \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " LOAD_IMMEDIATE_rax %1 \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !1 R0 LOADI8_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " SET_X0_TO_1 \n " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
common_recursion ( postfix_expr ) ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " XORI R0 R0 1 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " XOR_ebx_eax_into_eax \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " XOR_rbx_rax_into_rax \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '0' R0 R0 XOR R1 ARITH2_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " XOR_X0_X1_X0 \n " ) ;
2018-08-17 09:55:56 +01:00
}
2018-11-10 14:55:09 +00:00
else if ( ' ~ ' = = global_token - > s [ 0 ] )
{
common_recursion ( postfix_expr ) ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " NOT R0 R0 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " NOT_eax \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " NOT_rax \n " ) ;
2019-03-10 17:07:19 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '0' R0 R0 MVN_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " MVN_X0 \n " ) ;
2018-11-10 14:55:09 +00:00
}
2018-07-20 03:33:02 +01:00
else if ( global_token - > s [ 0 ] = = ' ( ' )
2018-01-21 03:56:50 +00:00
{
2018-07-20 03:33:02 +01:00
global_token = global_token - > next ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-07-20 03:33:02 +01:00
require_match ( " Error in Primary expression \n Didn't get ) \n " , " ) " ) ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
else if ( global_token - > s [ 0 ] = = ' \' ' ) primary_expr_char ( ) ;
else if ( global_token - > s [ 0 ] = = ' " ' ) primary_expr_string ( ) ;
else if ( in_set ( global_token - > s [ 0 ] , " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ " ) ) primary_expr_variable ( ) ;
else if ( in_set ( global_token - > s [ 0 ] , " 0123456789 " ) ) primary_expr_number ( ) ;
2018-07-20 03:33:02 +01:00
else primary_expr_failure ( ) ;
}
2018-08-18 20:23:58 +01:00
void expression ( )
2018-07-20 03:33:02 +01:00
{
2018-08-18 20:23:58 +01:00
bitwise_expr ( ) ;
2018-08-16 17:01:55 +01:00
if ( match ( " = " , global_token - > s ) )
{
2019-02-23 23:33:57 +00:00
char * store = " " ;
2018-08-17 09:55:56 +01:00
if ( ! match ( " ] " , global_token - > prev - > s ) | | ! match ( " char* " , current_target - > name ) )
2018-08-16 17:01:55 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) store = " STORE R0 R1 0 \n " ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) store = " STORE_INTEGER \n " ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) store = " STORE_INTEGER \n " ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) store = " !0 R0 STORE32 R1 MEMORY \n " ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) store = " STR_X0_[X1] \n " ;
2018-08-16 17:01:55 +01:00
}
else
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) store = " STORE8 R0 R1 0 \n " ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) store = " STORE_CHAR \n " ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) store = " STORE_CHAR \n " ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) store = " !0 R0 STORE8 R1 MEMORY \n " ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) store = " STR_BYTE_W0_[X1] \n " ;
2018-08-16 17:01:55 +01:00
}
2018-08-18 20:23:58 +01:00
common_recursion ( expression ) ;
emit_out ( store ) ;
2020-12-31 14:53:05 +00:00
current_target = integer ;
2018-08-16 17:01:55 +01:00
}
2018-01-21 03:56:50 +00:00
}
/* Process local variable */
2018-08-18 20:23:58 +01:00
void collect_local ( )
2018-01-21 03:56:50 +00:00
{
2020-11-09 02:13:12 +00:00
if ( NULL ! = break_target_func )
{
file_print ( " Local variable initialized inside of loop in file: " , stderr ) ;
line_error ( ) ;
file_print ( " \n Move the variable outside of the loop to resolve \n " , stderr ) ;
file_print ( " Otherwise the binary will segfault while running \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
}
2018-01-21 03:56:50 +00:00
struct type * type_size = type_name ( ) ;
struct token_list * a = sym_declare ( global_token - > s , type_size , function - > locals ) ;
2018-07-20 03:33:02 +01:00
if ( match ( " main " , function - > s ) & & ( NULL = = function - > locals ) )
{
2019-04-19 22:43:59 +01:00
if ( KNIGHT_NATIVE = = Architecture ) a - > depth = register_size ;
2019-04-18 01:19:17 +01:00
else if ( KNIGHT_POSIX = = Architecture ) a - > depth = 20 ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) a - > depth = - 20 ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) a - > depth = - 40 ;
2019-03-17 14:08:56 +00:00
else if ( ARMV7L = = Architecture ) a - > depth = 16 ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = 32 ; /* argc, argv, envp and the local (8 bytes each) */
2018-07-20 03:33:02 +01:00
}
else if ( ( NULL = = function - > arguments ) & & ( NULL = = function - > locals ) )
{
2019-04-19 22:43:59 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) a - > depth = register_size ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) a - > depth = - 8 ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) a - > depth = - 16 ;
2019-04-13 13:31:39 +01:00
else if ( ARMV7L = = Architecture ) a - > depth = 8 ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = register_size ;
2018-07-20 03:33:02 +01:00
}
else if ( NULL = = function - > locals )
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) a - > depth = function - > arguments - > depth + 8 ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) a - > depth = function - > arguments - > depth - 8 ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) a - > depth = function - > arguments - > depth - 16 ;
2019-03-18 02:34:26 +00:00
else if ( ARMV7L = = Architecture ) a - > depth = function - > arguments - > depth + 8 ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = function - > arguments - > depth + register_size ;
2018-07-20 03:33:02 +01:00
}
else
{
2019-04-19 22:43:59 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) a - > depth = function - > locals - > depth + register_size ;
else if ( X86 = = Architecture ) a - > depth = function - > locals - > depth - register_size ;
else if ( AMD64 = = Architecture ) a - > depth = function - > locals - > depth - register_size ;
else if ( ARMV7L = = Architecture ) a - > depth = function - > locals - > depth + register_size ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = function - > locals - > depth + register_size ;
2018-07-20 03:33:02 +01:00
}
2018-01-21 03:56:50 +00:00
function - > locals = a ;
2018-08-16 17:01:55 +01:00
2018-08-18 20:23:58 +01:00
emit_out ( " # Defining local " ) ;
emit_out ( global_token - > s ) ;
emit_out ( " \n " ) ;
2018-08-16 17:01:55 +01:00
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete local missing name \n " ) ;
2018-01-21 03:56:50 +00:00
2018-07-20 03:33:02 +01:00
if ( match ( " = " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " incomplete local assignment \n " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in collect_local \n Missing ; \n " , " ; " ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " PUSHR R0 R15 \t # " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " PUSH_eax \t # " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " PUSH_RAX \t # " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R0 } PUSH_ALWAYS \ t # " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " PUSH_X0 \t # " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( a - > s ) ;
emit_out ( " \n " ) ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void statement ( ) ;
2018-01-21 03:56:50 +00:00
/* Evaluate if statements */
2018-08-18 20:23:58 +01:00
void process_if ( )
2018-01-21 03:56:50 +00:00
{
2018-06-08 20:43:36 +01:00
char * number_string = numerate_number ( current_count ) ;
current_count = current_count + 1 ;
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " # IF_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_if \n MISSING ( \n " , " ( " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP.Z R0 @ELSE_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %ELSE_ " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %ELSE_ " ) ;
2019-03-10 15:24:13 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 CMPI8 R0 IMM_ALWAYS \n ^~ELSE_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " CBNZ_X0_PAST_BR \n LOAD_W16_AHEAD \n SKIP_32_DATA \n &ELSE_ " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-10 15:24:13 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_EQUAL \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_if \n MISSING ) \n " , " ) " ) ;
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-30 23:40:45 +00:00
require ( NULL ! = global_token , " Reached EOF inside of function \n " ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @_END_IF_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP %_END_IF_ " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP %_END_IF_ " ) ;
2019-03-10 15:24:13 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~_END_IF_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &_END_IF_ " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-10 15:24:13 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :ELSE_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
2018-02-01 04:14:40 +00:00
if ( match ( " else " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF where an else statement expected \n " ) ;
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-30 23:40:45 +00:00
require ( NULL ! = global_token , " Reached EOF inside of function \n " ) ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
emit_out ( " :_END_IF_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void process_for ( )
2018-01-21 03:56:50 +00:00
{
2018-08-26 21:34:31 +01:00
struct token_list * nested_locals = break_frame ;
2018-06-28 21:40:51 +01:00
char * nested_break_head = break_target_head ;
char * nested_break_func = break_target_func ;
char * nested_break_num = break_target_num ;
2020-02-28 23:48:58 +00:00
char * nested_continue_head = continue_target_head ;
2018-08-26 21:34:31 +01:00
char * number_string = numerate_number ( current_count ) ;
current_count = current_count + 1 ;
2018-06-28 21:40:51 +01:00
break_target_head = " FOR_END_ " ;
2020-02-28 23:48:58 +00:00
continue_target_head = " FOR_ITER_ " ;
2018-06-28 21:40:51 +01:00
break_target_num = number_string ;
2018-08-26 21:34:31 +01:00
break_frame = function - > locals ;
break_target_func = function - > s ;
2018-02-01 04:14:40 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " # FOR_initialization_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_for \n MISSING ( \n " , " ( " ) ;
2018-05-03 01:56:44 +01:00
if ( ! match ( " ; " , global_token - > s ) )
{
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-05-03 01:56:44 +01:00
}
2018-01-21 03:56:50 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :FOR_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_for \n MISSING ;1 \n " , " ; " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP.Z R0 @FOR_END_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %FOR_END_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %FOR_END_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 CMPI8 R0 IMM_ALWAYS \n ^~FOR_END_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " CBNZ_X0_PAST_BR \n LOAD_W16_AHEAD \n SKIP_32_DATA \n &FOR_END_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_EQUAL \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-17 00:03:56 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @FOR_THEN_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP %FOR_THEN_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP %FOR_THEN_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~FOR_THEN_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &FOR_THEN_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-17 00:03:56 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :FOR_ITER_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_for \n MISSING ;2 \n " , " ; " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @FOR_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP %FOR_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP %FOR_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~FOR_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &FOR_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-17 00:03:56 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :FOR_THEN_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_for \n MISSING ) \n " , " ) " ) ;
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-30 23:40:45 +00:00
require ( NULL ! = global_token , " Reached EOF inside of function \n " ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @FOR_ITER_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP %FOR_ITER_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP %FOR_ITER_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~FOR_ITER_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &FOR_ITER_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-17 00:03:56 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :FOR_END_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-02-01 04:14:40 +00:00
2018-06-28 21:40:51 +01:00
break_target_head = nested_break_head ;
break_target_func = nested_break_func ;
break_target_num = nested_break_num ;
2020-02-28 23:48:58 +00:00
continue_target_head = nested_continue_head ;
2018-08-10 22:30:48 +01:00
break_frame = nested_locals ;
2018-01-21 03:56:50 +00:00
}
/* Process Assembly statements */
2018-08-18 20:23:58 +01:00
void process_asm ( )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_asm \n MISSING ( \n " , " ( " ) ;
2019-02-23 23:33:57 +00:00
while ( ' " ' = = global_token - > s [ 0 ] )
{
2018-08-18 20:23:58 +01:00
emit_out ( ( global_token - > s + 1 ) ) ;
emit_out ( " \n " ) ;
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF inside asm statement \n " ) ;
2018-01-21 03:56:50 +00:00
}
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_asm \n MISSING ) \n " , " ) " ) ;
require_match ( " ERROR in process_asm \n MISSING ; \n " , " ; " ) ;
2018-01-25 01:00:22 +00:00
}
/* Process do while loops */
2018-08-18 20:23:58 +01:00
void process_do ( )
2018-01-25 01:00:22 +00:00
{
2018-08-26 21:34:31 +01:00
struct token_list * nested_locals = break_frame ;
2018-06-28 21:40:51 +01:00
char * nested_break_head = break_target_head ;
char * nested_break_func = break_target_func ;
char * nested_break_num = break_target_num ;
2020-02-28 23:48:58 +00:00
char * nested_continue_head = continue_target_head ;
2018-08-26 21:34:31 +01:00
char * number_string = numerate_number ( current_count ) ;
current_count = current_count + 1 ;
2018-06-28 21:40:51 +01:00
break_target_head = " DO_END_ " ;
2020-02-28 23:48:58 +00:00
continue_target_head = " DO_TEST_ " ;
2018-06-28 21:40:51 +01:00
break_target_num = number_string ;
2018-08-26 21:34:31 +01:00
break_frame = function - > locals ;
break_target_func = function - > s ;
2018-02-01 04:14:40 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :DO_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-25 01:00:22 +00:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF where do statement is expected \n " ) ;
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-30 23:40:45 +00:00
require ( NULL ! = global_token , " Reached EOF inside of function \n " ) ;
2018-01-25 01:00:22 +00:00
2020-02-28 23:48:58 +00:00
emit_out ( " :DO_TEST_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_do \n MISSING while \n " , " while " ) ;
require_match ( " ERROR in process_do \n MISSING ( \n " , " ( " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_do \n MISSING ) \n " , " ) " ) ;
require_match ( " ERROR in process_do \n MISSING ; \n " , " ; " ) ;
2018-01-25 01:00:22 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP.NZ R0 @DO_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " TEST \n JUMP_NE %DO_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " TEST \n JUMP_NE %DO_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 CMPI8 R0 IMM_ALWAYS \n ^~DO_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " CBZ_X0_PAST_BR \n LOAD_W16_AHEAD \n SKIP_32_DATA \n &DO_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 10:15:20 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_NE \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2019-03-17 00:03:56 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :DO_END_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-02-01 04:14:40 +00:00
2018-08-10 22:30:48 +01:00
break_frame = nested_locals ;
2018-06-28 21:40:51 +01:00
break_target_head = nested_break_head ;
break_target_func = nested_break_func ;
break_target_num = nested_break_num ;
2020-02-28 23:48:58 +00:00
continue_target_head = nested_continue_head ;
2018-01-21 03:56:50 +00:00
}
2018-01-25 01:00:22 +00:00
2018-01-21 03:56:50 +00:00
/* Process while loops */
2018-08-18 20:23:58 +01:00
void process_while ( )
2018-01-21 03:56:50 +00:00
{
2018-08-26 21:34:31 +01:00
struct token_list * nested_locals = break_frame ;
2018-06-28 21:40:51 +01:00
char * nested_break_head = break_target_head ;
char * nested_break_func = break_target_func ;
char * nested_break_num = break_target_num ;
2020-02-28 23:48:58 +00:00
char * nested_continue_head = continue_target_head ;
2018-08-26 21:34:31 +01:00
char * number_string = numerate_number ( current_count ) ;
current_count = current_count + 1 ;
2018-02-01 04:14:40 +00:00
2018-06-28 21:40:51 +01:00
break_target_head = " END_WHILE_ " ;
2020-02-28 23:48:58 +00:00
continue_target_head = " WHILE_ " ;
2018-06-28 21:40:51 +01:00
break_target_num = number_string ;
2018-08-26 21:34:31 +01:00
break_frame = function - > locals ;
break_target_func = function - > s ;
2018-02-01 04:14:40 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( " :WHILE_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
global_token = global_token - > next ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_while \n MISSING ( \n " , " ( " ) ;
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP.Z R0 @END_WHILE_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %END_WHILE_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " TEST \n JUMP_EQ %END_WHILE_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " !0 CMPI8 R0 IMM_ALWAYS \n ^~END_WHILE_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " CBNZ_X0_PAST_BR \n LOAD_W16_AHEAD \n SKIP_32_DATA \n &END_WHILE_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_EQUAL \t " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " # THEN_while_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in process_while \n MISSING ) \n " , " ) " ) ;
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-30 23:40:45 +00:00
require ( NULL ! = global_token , " Reached EOF inside of function \n " ) ;
2018-01-21 03:56:50 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @WHILE_ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP %WHILE_ " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP %WHILE_ " ) ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~WHILE_ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n &WHILE_ " ) ;
2018-08-18 20:23:58 +01:00
uniqueID_out ( function - > s , number_string ) ;
2019-03-17 00:03:56 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 \n " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " :END_WHILE_ " ) ;
uniqueID_out ( function - > s , number_string ) ;
2018-02-01 04:14:40 +00:00
2018-06-28 21:40:51 +01:00
break_target_head = nested_break_head ;
break_target_func = nested_break_func ;
break_target_num = nested_break_num ;
2020-02-28 23:48:58 +00:00
continue_target_head = nested_continue_head ;
2018-08-26 21:34:31 +01:00
break_frame = nested_locals ;
2018-01-21 03:56:50 +00:00
}
/* Ensure that functions return */
2018-08-18 20:23:58 +01:00
void return_result ( )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Incomplete return statement recieved \n " ) ;
2018-08-18 20:23:58 +01:00
if ( global_token - > s [ 0 ] ! = ' ; ' ) expression ( ) ;
2018-01-21 03:56:50 +00:00
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in return_result \n MISSING ; \n " , " ; " ) ;
2018-01-21 03:56:50 +00:00
2018-01-25 01:00:22 +00:00
struct token_list * i ;
for ( i = function - > locals ; NULL ! = i ; i = i - > next )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " POPR R1 R15 \t # _return_result_locals \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " POP_ebx \t # _return_result_locals \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " POP_RBX \t # _return_result_locals \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R1 } POP_ALWAYS \ t # _return_result_locals \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " POP_X1 \t # _return_result_locals \n " ) ;
2018-01-21 03:56:50 +00:00
}
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " RET R15 \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " RETURN \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " RETURN \n " ) ;
2019-03-30 13:25:52 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " '1' LR RETURN \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " RETURN \n " ) ;
2018-01-21 03:56:50 +00:00
}
2018-08-18 20:23:58 +01:00
void process_break ( )
2018-08-16 17:01:55 +01:00
{
if ( NULL = = break_target_head )
{
line_error ( ) ;
2020-02-28 23:48:58 +00:00
file_print ( " Not inside of a loop or case statement \n " , stderr ) ;
2018-08-16 17:01:55 +01:00
exit ( EXIT_FAILURE ) ;
}
struct token_list * i = function - > locals ;
while ( i ! = break_frame )
{
if ( NULL = = i ) break ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " POPR R1 R15 \t # break_cleanup_locals \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " POP_ebx \t # break_cleanup_locals \n " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " POP_RBX \t # break_cleanup_locals \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R1 } POP_ALWAYS \ t # break_cleanup_locals \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " POP_X1 \t # break_cleanup_locals \n " ) ;
2018-08-16 17:01:55 +01:00
i = i - > next ;
}
global_token = global_token - > next ;
2019-02-23 23:33:57 +00:00
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP % " ) ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP % " ) ;
2019-03-17 10:15:20 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n & " ) ;
2019-02-23 23:33:57 +00:00
2018-08-18 20:23:58 +01:00
emit_out ( break_target_head ) ;
emit_out ( break_target_func ) ;
emit_out ( " _ " ) ;
emit_out ( break_target_num ) ;
2019-03-17 10:15:20 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " \n " ) ;
2018-08-26 21:34:31 +01:00
require_match ( " ERROR in break statement \n Missing ; \n " , " ; " ) ;
2018-08-16 17:01:55 +01:00
}
2020-02-28 23:48:58 +00:00
void process_contine ( )
{
if ( NULL = = continue_target_head )
{
line_error ( ) ;
file_print ( " Not inside of a loop \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
}
global_token = global_token - > next ;
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @ " ) ;
else if ( X86 = = Architecture ) emit_out ( " JUMP % " ) ;
else if ( AMD64 = = Architecture ) emit_out ( " JUMP % " ) ;
else if ( ARMV7L = = Architecture ) emit_out ( " ^~ " ) ;
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n & " ) ;
emit_out ( continue_target_head ) ;
emit_out ( break_target_func ) ;
emit_out ( " _ " ) ;
emit_out ( break_target_num ) ;
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS " ) ;
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 " ) ;
emit_out ( " \n " ) ;
require_match ( " ERROR in continue statement \n Missing ; \n " , " ; " ) ;
}
2018-08-18 20:23:58 +01:00
void recursive_statement ( )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF in recursive statement \n " ) ;
2018-01-21 03:56:50 +00:00
struct token_list * frame = function - > locals ;
2018-02-01 04:14:40 +00:00
while ( ! match ( " } " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
statement ( ) ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF in recursive statement prior to } \n " ) ;
2018-01-21 03:56:50 +00:00
}
global_token = global_token - > next ;
/* Clean up any locals added */
2019-02-23 23:33:57 +00:00
2019-06-04 02:01:14 +01:00
if ( ( ( X86 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) | |
( ( AMD64 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) | |
( ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) & & ! match ( " RET R15 \n " , output_list - > s ) ) | |
2020-02-01 20:23:49 +00:00
( ( ARMV7L = = Architecture ) & & ! match ( " '1' LR RETURN \n " , output_list - > s ) ) | |
( ( AARCH64 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) )
2018-01-21 03:56:50 +00:00
{
2018-08-16 17:01:55 +01:00
struct token_list * i ;
for ( i = function - > locals ; frame ! = i ; i = i - > next )
2018-01-21 03:56:50 +00:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " POPR R1 R15 \t # _recursive_statement_locals \n " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " POP_ebx \t # _recursive_statement_locals \n " ) ;
2019-04-18 01:19:17 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " POP_RBX \t # _recursive_statement_locals \n " ) ;
2019-03-10 13:33:45 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " { R1 } POP_ALWAYS \ t # _recursive_statement_locals \ n " );
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " POP_X1 \t # _recursive_statement_locals \n " ) ;
2018-01-21 03:56:50 +00:00
}
}
2018-08-16 17:01:55 +01:00
function - > locals = frame ;
2018-01-21 03:56:50 +00:00
}
/*
* statement :
* { statement - list - opt }
* type - name identifier ;
* type - name identifier = expression ;
* if ( expression ) statement
* if ( expression ) statement else statement
2018-01-25 01:00:22 +00:00
* do statement while ( expression ) ;
2018-01-21 03:56:50 +00:00
* while ( expression ) statement
* for ( expression ; expression ; expression ) statement
* asm ( " assembly " . . . " assembly " ) ;
2018-01-25 01:00:22 +00:00
* goto label ;
* label :
2018-01-21 03:56:50 +00:00
* return ;
2018-02-01 04:14:40 +00:00
* break ;
2018-01-21 03:56:50 +00:00
* expr ;
*/
2018-02-01 04:14:40 +00:00
2018-08-16 17:01:55 +01:00
struct type * lookup_type ( char * s , struct type * start ) ;
2018-08-18 20:23:58 +01:00
void statement ( )
2018-01-21 03:56:50 +00:00
{
2020-12-31 14:53:05 +00:00
/* Always an integer until told otherwise */
current_target = integer ;
2018-01-21 03:56:50 +00:00
if ( global_token - > s [ 0 ] = = ' { ' )
{
2018-08-18 20:23:58 +01:00
recursive_statement ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-01-25 01:00:22 +00:00
else if ( ' : ' = = global_token - > s [ 0 ] )
{
2018-08-18 20:23:58 +01:00
emit_out ( global_token - > s ) ;
emit_out ( " \t #C goto label \n " ) ;
2018-01-25 01:00:22 +00:00
global_token = global_token - > next ;
}
2018-08-16 17:01:55 +01:00
else if ( ( NULL ! = lookup_type ( global_token - > s , prim_types ) ) | |
2018-07-20 03:33:02 +01:00
match ( " struct " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
collect_local ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " if " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
process_if ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " do " , global_token - > s ) )
2018-01-25 01:00:22 +00:00
{
2018-08-18 20:23:58 +01:00
process_do ( ) ;
2018-01-25 01:00:22 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " while " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
process_while ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " for " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
process_for ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " asm " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
process_asm ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " goto " , global_token - > s ) )
2018-01-25 01:00:22 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " naked goto is not supported \n " ) ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) emit_out ( " JUMP @ " ) ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) emit_out ( " JUMP % " ) ;
2019-04-23 00:30:08 +01:00
else if ( AMD64 = = Architecture ) emit_out ( " JUMP % " ) ;
2019-03-17 10:15:20 +00:00
else if ( ARMV7L = = Architecture ) emit_out ( " ^~ " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " LOAD_W16_AHEAD \n SKIP_32_DATA \n & " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( global_token - > s ) ;
2019-03-17 10:15:20 +00:00
if ( ARMV7L = = Architecture ) emit_out ( " JUMP_ALWAYS " ) ;
2020-02-01 20:23:49 +00:00
else if ( AARCH64 = = Architecture ) emit_out ( " \n BR_X16 " ) ;
2018-08-18 20:23:58 +01:00
emit_out ( " \n " ) ;
2018-01-25 01:00:22 +00:00
global_token = global_token - > next ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in statement \n Missing ; \n " , " ; " ) ;
2018-01-25 01:00:22 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " return " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
return_result ( ) ;
2018-01-21 03:56:50 +00:00
}
2018-02-01 04:14:40 +00:00
else if ( match ( " break " , global_token - > s ) )
{
2018-08-18 20:23:58 +01:00
process_break ( ) ;
2018-06-02 01:05:27 +01:00
}
else if ( match ( " continue " , global_token - > s ) )
{
2020-02-28 23:48:58 +00:00
process_contine ( ) ;
2018-02-01 04:14:40 +00:00
}
2018-01-21 03:56:50 +00:00
else
{
2018-08-18 20:23:58 +01:00
expression ( ) ;
2018-06-02 01:05:27 +01:00
require_match ( " ERROR in statement \n MISSING ; \n " , " ; " ) ;
2018-01-21 03:56:50 +00:00
}
}
/* Collect function arguments */
2018-08-18 20:23:58 +01:00
void collect_arguments ( )
2018-01-21 03:56:50 +00:00
{
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Recieved EOF when attempting to collect arguments \n " ) ;
2020-10-17 03:07:06 +01:00
struct type * type_size ;
struct token_list * a ;
2018-01-21 03:56:50 +00:00
2018-02-01 04:14:40 +00:00
while ( ! match ( " ) " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2020-10-17 03:07:06 +01:00
type_size = type_name ( ) ;
2018-01-21 03:56:50 +00:00
if ( global_token - > s [ 0 ] = = ' ) ' )
{
2018-08-16 17:01:55 +01:00
/* foo(int,char,void) doesn't need anything done */
continue ;
2018-01-21 03:56:50 +00:00
}
else if ( global_token - > s [ 0 ] ! = ' , ' )
{
/* deal with foo(int a, char b) */
2020-10-17 03:07:06 +01:00
a = sym_declare ( global_token - > s , type_size , function - > arguments ) ;
2018-10-17 21:08:04 +01:00
if ( NULL = = function - > arguments )
2018-07-20 03:33:02 +01:00
{
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) a - > depth = 0 ;
2019-02-26 23:04:49 +00:00
else if ( X86 = = Architecture ) a - > depth = - 4 ;
2019-04-19 22:43:59 +01:00
else if ( AMD64 = = Architecture ) a - > depth = - 8 ;
2019-03-17 00:03:56 +00:00
else if ( ARMV7L = = Architecture ) a - > depth = 4 ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = register_size ;
2018-07-20 03:33:02 +01:00
}
else
{
2019-04-19 22:43:59 +01:00
if ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) a - > depth = function - > arguments - > depth + register_size ;
else if ( X86 = = Architecture ) a - > depth = function - > arguments - > depth - register_size ;
else if ( AMD64 = = Architecture ) a - > depth = function - > arguments - > depth - register_size ;
else if ( ARMV7L = = Architecture ) a - > depth = function - > arguments - > depth + register_size ;
2020-02-07 23:16:54 +00:00
else if ( AARCH64 = = Architecture ) a - > depth = function - > arguments - > depth + register_size ;
2018-07-20 03:33:02 +01:00
}
2018-08-16 17:01:55 +01:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Incomplete argument list \n " ) ;
2018-01-21 03:56:50 +00:00
function - > arguments = a ;
}
/* ignore trailing comma (needed for foo(bar(), 1); expressions*/
2020-01-22 23:03:28 +00:00
if ( global_token - > s [ 0 ] = = ' , ' )
{
global_token = global_token - > next ;
require ( NULL ! = global_token , " naked comma in collect arguments \n " ) ;
}
require ( NULL ! = global_token , " Argument list never completed \n " ) ;
2018-01-21 03:56:50 +00:00
}
global_token = global_token - > next ;
}
2018-08-18 20:23:58 +01:00
void declare_function ( )
2018-01-21 03:56:50 +00:00
{
2018-06-08 20:43:36 +01:00
current_count = 0 ;
2018-08-18 20:23:58 +01:00
function = sym_declare ( global_token - > prev - > s , NULL , global_function_list ) ;
2018-01-21 03:56:50 +00:00
/* allow previously defined functions to be looked up */
2018-08-18 20:23:58 +01:00
global_function_list = function ;
2019-04-18 01:19:17 +01:00
if ( ( KNIGHT_NATIVE = = Architecture ) & & match ( " main " , function - > s ) )
{
require_match ( " Impossible error ( vanished \n " , " ( " ) ;
require_match ( " Reality ERROR (USING KNIGHT-NATIVE) \n Hardware does not support arguments \n thus neither can main on this architecture \n try tape_01 and tape_02 instead \n " , " ) " ) ;
}
else collect_arguments ( ) ;
2018-01-21 03:56:50 +00:00
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Function definitions either need to be prototypes or full \n " ) ;
2018-01-21 03:56:50 +00:00
/* If just a prototype don't waste time */
if ( global_token - > s [ 0 ] = = ' ; ' ) global_token = global_token - > next ;
else
{
2018-08-18 20:23:58 +01:00
emit_out ( " # Defining function " ) ;
emit_out ( function - > s ) ;
emit_out ( " \n " ) ;
emit_out ( " :FUNCTION_ " ) ;
emit_out ( function - > s ) ;
emit_out ( " \n " ) ;
statement ( ) ;
2018-01-21 03:56:50 +00:00
/* Prevent duplicate RETURNS */
2019-06-04 02:01:14 +01:00
if ( ( ( KNIGHT_POSIX = = Architecture ) | | ( KNIGHT_NATIVE = = Architecture ) ) & & ! match ( " RET R15 \n " , output_list - > s ) ) emit_out ( " RET R15 \n " ) ;
else if ( ( X86 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) emit_out ( " RETURN \n " ) ;
else if ( ( AMD64 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) emit_out ( " RETURN \n " ) ;
else if ( ( ARMV7L = = Architecture ) & & ! match ( " '1' LR RETURN \n " , output_list - > s ) ) emit_out ( " '1' LR RETURN \n " ) ;
2020-02-01 20:23:49 +00:00
else if ( ( AARCH64 = = Architecture ) & & ! match ( " RETURN \n " , output_list - > s ) ) emit_out ( " RETURN \n " ) ;
2018-01-21 03:56:50 +00:00
}
}
/*
* program :
* declaration
* declaration program
*
* declaration :
* CONSTANT identifer value
* type - name identifier ;
* type - name identifier ( parameter - list ) ;
* type - name identifier ( parameter - list ) statement
*
* parameter - list :
* parameter - declaration
* parameter - list , parameter - declaration
*
* parameter - declaration :
* type - name identifier - opt
*/
2019-06-04 02:01:14 +01:00
void program ( )
2018-01-21 03:56:50 +00:00
{
2018-08-18 20:23:58 +01:00
function = NULL ;
2018-10-17 21:08:04 +01:00
Address_of = FALSE ;
2018-02-24 02:18:23 +00:00
struct type * type_size ;
2021-01-09 23:34:25 +00:00
int size ;
2018-08-12 18:11:02 +01:00
2018-01-21 03:56:50 +00:00
new_type :
2019-06-04 02:01:14 +01:00
if ( NULL = = global_token ) return ;
2018-08-12 18:11:02 +01:00
if ( match ( " CONSTANT " , global_token - > s ) )
{
2018-08-21 01:41:37 +01:00
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " CONSTANT lacks a name \n " ) ;
2018-08-21 01:41:37 +01:00
global_constant_list = sym_declare ( global_token - > s , NULL , global_constant_list ) ;
2019-04-23 00:30:08 +01:00
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token - > next , " CONSTANT lacks a value \n " ) ;
2019-04-23 00:30:08 +01:00
if ( match ( " sizeof " , global_token - > next - > s ) )
{
global_token = global_token - > next - > next ;
require_match ( " ERROR in CONSTANT with sizeof \n Missing ( \n " , " ( " ) ;
struct type * a = type_name ( ) ;
require_match ( " ERROR in CONSTANT with sizeof \n Missing ) \n " , " ) " ) ;
global_token - > prev - > s = numerate_number ( a - > size ) ;
global_constant_list - > arguments = global_token - > prev ;
}
else
{
global_constant_list - > arguments = global_token - > next ;
global_token = global_token - > next - > next ;
}
2018-08-12 18:11:02 +01:00
}
2021-01-03 03:00:02 +00:00
else if ( match ( " typedef " , global_token - > s ) )
{
/* typedef $TYPE $NAME; */
global_token = global_token - > next ;
type_size = type_name ( ) ;
type_size = mirror_type ( type_size , global_token - > s ) ;
add_primitive ( type_size ) ;
global_token = global_token - > next ;
require_match ( " ERROR in typedef statement \n Missing ; \n " , " ; " ) ;
}
2018-08-12 18:11:02 +01:00
else
{
2021-01-05 19:53:06 +00:00
require ( ' # ' ! = global_token - > s [ 0 ] , " unhandled macro directive \n " ) ;
2021-01-04 12:45:07 +00:00
require ( ! match ( " \n " , global_token - > s ) , " unexpected newline token \n " ) ;
2018-08-12 18:11:02 +01:00
type_size = type_name ( ) ;
if ( NULL = = type_size )
2018-01-21 03:56:50 +00:00
{
2018-08-12 18:11:02 +01:00
goto new_type ;
2018-01-21 03:56:50 +00:00
}
2021-01-09 23:34:25 +00:00
require ( NULL ! = global_token - > next , " Unterminated global \n " ) ;
if ( match ( " [ " , global_token - > next - > s ) )
{
maybe_bootstrap_error ( " global array definitions " ) ;
globals_list = emit ( " :GLOBAL_ " , globals_list ) ;
globals_list = emit ( global_token - > s , globals_list ) ;
globals_list = emit ( " \n &GLOBAL_STORAGE_ " , globals_list ) ;
globals_list = emit ( global_token - > s , globals_list ) ;
if ( AARCH64 = = Architecture | | AMD64 = = Architecture )
{
globals_list = emit ( " %0 " , globals_list ) ;
}
globals_list = emit ( " \n :GLOBAL_STORAGE_ " , globals_list ) ;
globals_list = emit ( global_token - > s , globals_list ) ;
global_symbol_list = sym_declare ( global_token - > s , type_size - > indirect , global_symbol_list ) ;
require ( NULL ! = global_token - > next - > next , " Unterminated global \n " ) ;
global_token = global_token - > next - > next ;
/* length */
size = numerate_string ( global_token - > s ) ;
globals_list = emit ( " \n ' " , globals_list ) ;
while ( 0 ! = size )
{
globals_list = emit ( " 00 " , globals_list ) ;
size = size - 1 ;
}
globals_list = emit ( " ' \n " , globals_list ) ;
global_token = global_token - > next ;
require_match ( " missing close bracket \n " , " ] " ) ;
require_match ( " missing ; \n " , " ; " ) ;
goto new_type ;
}
2018-08-12 18:11:02 +01:00
/* Add to global symbol table */
global_symbol_list = sym_declare ( global_token - > s , type_size , global_symbol_list ) ;
global_token = global_token - > next ;
if ( match ( " ; " , global_token - > s ) )
2018-01-21 03:56:50 +00:00
{
2018-08-12 18:11:02 +01:00
/* Ensure 4 bytes are allocated for the global */
globals_list = emit ( " :GLOBAL_ " , globals_list ) ;
globals_list = emit ( global_token - > prev - > s , globals_list ) ;
2020-01-07 01:21:26 +00:00
globals_list = emit ( " \n NULL \n " , globals_list ) ;
2018-01-21 03:56:50 +00:00
2018-08-12 18:11:02 +01:00
global_token = global_token - > next ;
}
2018-08-18 20:23:58 +01:00
else if ( match ( " ( " , global_token - > s ) ) declare_function ( ) ;
2018-08-12 18:11:02 +01:00
else if ( match ( " = " , global_token - > s ) )
{
/* Store the global's value*/
globals_list = emit ( " :GLOBAL_ " , globals_list ) ;
globals_list = emit ( global_token - > prev - > s , globals_list ) ;
globals_list = emit ( " \n " , globals_list ) ;
global_token = global_token - > next ;
2020-01-22 23:03:28 +00:00
require ( NULL ! = global_token , " Global locals value in assignment \n " ) ;
2018-08-12 18:11:02 +01:00
if ( in_set ( global_token - > s [ 0 ] , " 0123456789 " ) )
{ /* Assume Int */
globals_list = emit ( " % " , globals_list ) ;
globals_list = emit ( global_token - > s , globals_list ) ;
2018-06-28 21:40:51 +01:00
globals_list = emit ( " \n " , globals_list ) ;
2018-06-26 22:03:17 +01:00
}
2018-08-12 18:11:02 +01:00
else if ( ( ' " ' = = global_token - > s [ 0 ] ) )
{ /* Assume a string*/
2019-04-18 15:48:41 +01:00
globals_list = emit ( " &GLOBAL_ " , globals_list ) ;
globals_list = emit ( global_token - > prev - > prev - > s , globals_list ) ;
globals_list = emit ( " _contents \n " , globals_list ) ;
globals_list = emit ( " :GLOBAL_ " , globals_list ) ;
globals_list = emit ( global_token - > prev - > prev - > s , globals_list ) ;
globals_list = emit ( " _contents \n " , globals_list ) ;
2018-08-12 18:11:02 +01:00
globals_list = emit ( parse_string ( global_token - > s ) , globals_list ) ;
}
2018-01-21 03:56:50 +00:00
else
{
2018-08-27 02:15:32 +01:00
line_error ( ) ;
2019-10-23 20:04:14 +01:00
file_print ( " Received " , stderr ) ;
2018-01-25 01:00:22 +00:00
file_print ( global_token - > s , stderr ) ;
2018-06-02 01:05:27 +01:00
file_print ( " in program \n " , stderr ) ;
2018-01-21 03:56:50 +00:00
exit ( EXIT_FAILURE ) ;
}
2018-08-12 18:11:02 +01:00
global_token = global_token - > next ;
require_match ( " ERROR in Program \n Missing ; \n " , " ; " ) ;
}
else
{
2018-08-27 02:15:32 +01:00
line_error ( ) ;
2019-10-23 20:04:14 +01:00
file_print ( " Received " , stderr ) ;
2018-08-12 18:11:02 +01:00
file_print ( global_token - > s , stderr ) ;
file_print ( " in program \n " , stderr ) ;
exit ( EXIT_FAILURE ) ;
2018-01-21 03:56:50 +00:00
}
}
2018-08-12 18:11:02 +01:00
goto new_type ;
2018-01-21 03:56:50 +00:00
}
2020-12-19 11:50:11 +00:00
void recursive_output ( struct token_list * head , FILE * out )
2018-01-21 03:56:50 +00:00
{
2020-12-19 11:50:11 +00:00
struct token_list * i = reverse_list ( head ) ;
while ( NULL ! = i )
{
file_print ( i - > s , out ) ;
i = i - > next ;
}
2018-01-21 03:56:50 +00:00
}
2021-01-03 13:32:35 +00:00
void output_tokens ( struct token_list * i , FILE * out )
{
while ( NULL ! = i )
{
file_print ( i - > s , out ) ;
file_print ( " " , out ) ;
i = i - > next ;
}
}