two pass encoding and resizing references #22
							
								
								
									
										48
									
								
								src/ast.h
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								src/ast.h
									
									
									
									
									
								
							@@ -5,6 +5,7 @@
 | 
				
			|||||||
#include "error.h"
 | 
					#include "error.h"
 | 
				
			||||||
#include "lexer.h"
 | 
					#include "lexer.h"
 | 
				
			||||||
#include "tokenlist.h"
 | 
					#include "tokenlist.h"
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,10 +76,26 @@ typedef struct register_ {
 | 
				
			|||||||
} register_t;
 | 
					} register_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct opcode_encoding {
 | 
					typedef struct opcode_encoding {
 | 
				
			||||||
    uint8_t encoding[32];
 | 
					    uint8_t buffer[32];
 | 
				
			||||||
    size_t len;
 | 
					    size_t len;
 | 
				
			||||||
} opcode_encoding_t;
 | 
					} opcode_encoding_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct instruction {
 | 
				
			||||||
 | 
					    bool has_reference;
 | 
				
			||||||
 | 
					    opcode_encoding_t encoding;
 | 
				
			||||||
 | 
					    int64_t address;
 | 
				
			||||||
 | 
					} instruction_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct reference {
 | 
				
			||||||
 | 
					    int64_t offset;
 | 
				
			||||||
 | 
					    int64_t address;
 | 
				
			||||||
 | 
					    operand_size_t size;
 | 
				
			||||||
 | 
					} reference_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    int64_t address;
 | 
				
			||||||
 | 
					} label_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ast_node {
 | 
					struct ast_node {
 | 
				
			||||||
    node_id_t id;
 | 
					    node_id_t id;
 | 
				
			||||||
    tokenlist_entry_t *token_entry;
 | 
					    tokenlist_entry_t *token_entry;
 | 
				
			||||||
@@ -89,10 +106,37 @@ struct ast_node {
 | 
				
			|||||||
    union {
 | 
					    union {
 | 
				
			||||||
        register_t reg;
 | 
					        register_t reg;
 | 
				
			||||||
        number_t number;
 | 
					        number_t number;
 | 
				
			||||||
        opcode_encoding_t encoding;
 | 
					        instruction_t instruction;
 | 
				
			||||||
 | 
					        reference_t reference;
 | 
				
			||||||
 | 
					        label_t label;
 | 
				
			||||||
    } value;
 | 
					    } value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline register_t *ast_node_register_value(ast_node_t *node) {
 | 
				
			||||||
 | 
					    assert(node->id == NODE_REGISTER);
 | 
				
			||||||
 | 
					    return &node->value.reg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline number_t *ast_node_number_value(ast_node_t *node) {
 | 
				
			||||||
 | 
					    assert(node->id == NODE_NUMBER);
 | 
				
			||||||
 | 
					    return &node->value.number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline instruction_t *ast_node_instruction_value(ast_node_t *node) {
 | 
				
			||||||
 | 
					    assert(node->id == NODE_INSTRUCTION);
 | 
				
			||||||
 | 
					    return &node->value.instruction;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline reference_t *ast_node_reference_value(ast_node_t *node) {
 | 
				
			||||||
 | 
					    assert(node->id == NODE_LABEL_REFERENCE);
 | 
				
			||||||
 | 
					    return &node->value.reference;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline label_t *ast_node_label_value(ast_node_t *node) {
 | 
				
			||||||
 | 
					    assert(node->id == NODE_LABEL);
 | 
				
			||||||
 | 
					    return &node->value.label;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Allocates a new AST node
 | 
					 * @brief Allocates a new AST node
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -481,7 +481,7 @@ error_t *encoder_encode_instruction(encoder_t *encoder,
 | 
				
			|||||||
        return err;
 | 
					        return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // produce the actual encoding output in the NODE_INSTRUCTION value
 | 
					    // produce the actual encoding output in the NODE_INSTRUCTION value
 | 
				
			||||||
    uint8_t *output = instruction->value.encoding.encoding;
 | 
					    uint8_t *output = instruction->value.instruction.encoding.buffer;
 | 
				
			||||||
    size_t output_len = 0;
 | 
					    size_t output_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Handle prefixes
 | 
					    // Handle prefixes
 | 
				
			||||||
@@ -500,7 +500,7 @@ error_t *encoder_encode_instruction(encoder_t *encoder,
 | 
				
			|||||||
    memcpy(output + output_len, encoding->buffer, encoding->len);
 | 
					    memcpy(output + output_len, encoding->buffer, encoding->len);
 | 
				
			||||||
    output_len += encoding->len;
 | 
					    output_len += encoding->len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    instruction->value.encoding.len = output_len;
 | 
					    instruction->value.instruction.encoding.len = output_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return nullptr;
 | 
					    return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,7 +88,8 @@ error_t *print_encoding(tokenlist_t *list) {
 | 
				
			|||||||
        if (node->id != NODE_INSTRUCTION)
 | 
					        if (node->id != NODE_INSTRUCTION)
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print_hex(node->value.encoding.len, node->value.encoding.encoding);
 | 
					        print_hex(node->value.instruction.encoding.len,
 | 
				
			||||||
 | 
					                  node->value.instruction.encoding.buffer);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    encoder_free(encoder);
 | 
					    encoder_free(encoder);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user