Updated the parser to better handle parameters, sort of and including a string length assembly program to use as a test for the whole assembler.
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
void Disassemble(unsigned char image[HIGHMEMORY]);
|
//void Disassemble(unsigned char image[HIGHMEMORY]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ typedef struct {
|
|||||||
Mnemonic Mnemonic;
|
Mnemonic Mnemonic;
|
||||||
OpcodeParameter ParameterOneType;
|
OpcodeParameter ParameterOneType;
|
||||||
OpcodeParameter ParameterTwoType;
|
OpcodeParameter ParameterTwoType;
|
||||||
|
int LineNumber;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int Constant;
|
int Constant;
|
||||||
|
|||||||
+25
-25
@@ -1,27 +1,27 @@
|
|||||||
;.org 0x100
|
.db video_start 0xF37F
|
||||||
.db msg "Hello, world!", 0
|
.db msg "Hello, world!", 0
|
||||||
.db more_stuff "AA", 0
|
|
||||||
copy r7, msg ; //
|
|
||||||
;cmp r8, msg ;1000 1111
|
|
||||||
;add r4, 0x42
|
|
||||||
;sub r1, r8
|
|
||||||
int 20
|
|
||||||
jz 45
|
|
||||||
jmp msg
|
|
||||||
in 10
|
|
||||||
call more_stuff
|
|
||||||
ret
|
|
||||||
yld
|
|
||||||
|
|
||||||
;copy r1, 45 ;//B0 = 10110000
|
load r1, [msg] ; Because the lod* instructions can't load an address
|
||||||
;copy 2, 45
|
; from anything but a register, this becomes laa r1, [msg]
|
||||||
;loop:
|
|
||||||
; cmp r1, 0
|
;Routine: string_length
|
||||||
; jz loop
|
;In: String address in r1
|
||||||
; add r1, 1
|
;Out: Length in R2
|
||||||
;mov r1, 5 ; move the immediate value 5 into r1
|
|
||||||
;add r1,5 ; add 5 into r1
|
string_length:
|
||||||
;int 21 ; maybe that will call some string drawing BIOS-like routine
|
loadb r3, [r1] ; Load the byte from the address in R1, into R3
|
||||||
;ret
|
load r2, 0 ; String length
|
||||||
; 4 byte header
|
cmp r3, 0 ; Is R3 a null byte?
|
||||||
; | Address of First Opcode (2 bytes) | End of Binary (2 bytes) |
|
je end
|
||||||
|
inc r2
|
||||||
|
|
||||||
|
start:
|
||||||
|
inc r1 ; next char
|
||||||
|
loadb r3, [r1] ; Load the next character byte into R3
|
||||||
|
cmpi r3, 0 ; Null byte?
|
||||||
|
je end
|
||||||
|
inc r2 ; Nope, increment the length counter
|
||||||
|
jmp start
|
||||||
|
|
||||||
|
end:
|
||||||
|
ret
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ const unsigned char ADDRESSMASK = 0x10; //0001 0000
|
|||||||
|
|
||||||
int IsRegisterPattern(unsigned char pattern, char* lexeme);
|
int IsRegisterPattern(unsigned char pattern, char* lexeme);
|
||||||
void GetParameter(unsigned char instruction, char* text);
|
void GetParameter(unsigned char instruction, char* text);
|
||||||
|
/*
|
||||||
void Disassemble(unsigned char image[HIGHMEMORY]) {
|
void Disassemble(unsigned char image[HIGHMEMORY]) {
|
||||||
Image = image;
|
Image = image;
|
||||||
int position = image[0] + image[1];
|
int position = image[0] + image[1];
|
||||||
@@ -117,7 +117,7 @@ void Disassemble(unsigned char image[HIGHMEMORY]) {
|
|||||||
memset(parameter2, '\0', sizeof(char) * 32);
|
memset(parameter2, '\0', sizeof(char) * 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
int IsRegisterPattern(unsigned char pattern, char* lexeme) {
|
int IsRegisterPattern(unsigned char pattern, char* lexeme) {
|
||||||
if (pattern > 8) {
|
if (pattern > 8) {
|
||||||
lexeme[0] = '\0';
|
lexeme[0] = '\0';
|
||||||
|
|||||||
+47
-45
@@ -10,19 +10,14 @@ int CurrentToken = 0;
|
|||||||
//int HeapStart = 4; // zero indexed, used for declared variables.
|
//int HeapStart = 4; // zero indexed, used for declared variables.
|
||||||
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
|
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
|
||||||
|
|
||||||
//IROpcode* CreateIROpcode(Mnemonic mnemonic);
|
|
||||||
void PrintSymbols(void);
|
void PrintSymbols(void);
|
||||||
void HandleOperation(void);
|
void HandleOperation(void);
|
||||||
void HandleAssemblerDirective(void);
|
void HandleAssemblerDirective(void);
|
||||||
void AdvanceParser(void);
|
void AdvanceParser(void);
|
||||||
|
void IgnoreParserLine(void);
|
||||||
Token* PeekToken(void);
|
Token* PeekToken(void);
|
||||||
int ParserAtEnd(void);
|
int ParserAtEnd(void);
|
||||||
int Expect(int, ...);
|
int Expect(int, ...);
|
||||||
//List* SymbolsTable;
|
|
||||||
// unsigned int HeapTop = 4;
|
|
||||||
// unsigned int ProgramCounter = 0;
|
|
||||||
// unsigned char Heap[HIGHMEMORY];
|
|
||||||
// unsigned char Memory[HIGHMEMORY];
|
|
||||||
IRState MachineState;
|
IRState MachineState;
|
||||||
|
|
||||||
IRState* ParseTokens(List* tokens) {
|
IRState* ParseTokens(List* tokens) {
|
||||||
@@ -40,9 +35,8 @@ IRState* ParseTokens(List* tokens) {
|
|||||||
Token* t = PeekToken();
|
Token* t = PeekToken();
|
||||||
|
|
||||||
switch(t->Class) {
|
switch(t->Class) {
|
||||||
case DirectiveClass:
|
case DirectiveClass: //Maybe these should be ignored, let another process handle that.
|
||||||
//HandleAssemblerDirective();
|
IgnoreParserLine();
|
||||||
//while(!ParserAtEnd() && (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != NewLine)) AdvanceParser();
|
|
||||||
break;
|
break;
|
||||||
case MnemonicClass:
|
case MnemonicClass:
|
||||||
HandleOperation();
|
HandleOperation();
|
||||||
@@ -50,7 +44,7 @@ IRState* ParseTokens(List* tokens) {
|
|||||||
case LabelClass:
|
case LabelClass:
|
||||||
printf("%s: \n", t->Lemexe);
|
printf("%s: \n", t->Lemexe);
|
||||||
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
|
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
|
||||||
//AddSymbol(t, 2, ProgramCounter, 1);
|
AdvanceParser(); //Consume the NewLine
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
||||||
@@ -161,45 +155,43 @@ void HandleOperation() {
|
|||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
|
|
||||||
while(!ParserAtEnd()) {
|
//No parameters here, we have a line break.
|
||||||
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
|
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
|
||||||
break;
|
goto InsertInstruction;
|
||||||
}
|
|
||||||
|
|
||||||
ins->ParameterOneType = GetParameterType(&token);
|
|
||||||
|
|
||||||
if (ins->ParameterOneType == NoParameter) {
|
|
||||||
AdvanceParser(); //Comsume the line end
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PeekToken()->Class == PunctuationClass) {
|
|
||||||
if (PeekToken()->Value.Punctuation == NewLine) {
|
|
||||||
AdvanceParser(); //Comsume end line.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (PeekToken()->Value.Punctuation != Comma) {
|
|
||||||
fprintf(stderr, "[Error] Line %d: comma need for %s\n", token->LineNumber, mn);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "[Error] Line %d: comma needed for %s\n", token->LineNumber, mn);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
AdvanceParser(); //Comsume the comma
|
|
||||||
|
|
||||||
ins->ParameterTwoType = GetParameterType(&token);
|
|
||||||
|
|
||||||
AdvanceParser();//comsume the end line.
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
//AdvanceParser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ins->ParameterOneType = GetParameterType(&token);
|
||||||
|
|
||||||
|
if (ins->ParameterOneType == NoParameter) {
|
||||||
|
//This would be an error if the next token isn't a line break.
|
||||||
|
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) {
|
||||||
|
fprintf(stderr, "[Error] Line %d: Syntax error, expected line break but got %s.\n", token->LineNumber, token->Lemexe);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto InsertInstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
|
||||||
|
goto InsertInstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) {
|
||||||
|
//Syntax error
|
||||||
|
fprintf(stderr, "[Error] Line %d: Expected comma.\n", token->LineNumber);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
AdvanceParser(); //Consume the comma
|
||||||
|
|
||||||
|
ins->ParameterTwoType = GetParameterType(&token);
|
||||||
|
|
||||||
|
InsertInstruction:
|
||||||
|
|
||||||
AddListItem(ins, sizeof(Instruction), MachineState.Instructions);
|
AddListItem(ins, sizeof(Instruction), MachineState.Instructions);
|
||||||
|
|
||||||
|
AdvanceParser(); //Consume the line break
|
||||||
|
|
||||||
free(ins);
|
free(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,4 +643,14 @@ int ParserAtEnd(void) {
|
|||||||
|
|
||||||
Token* PeekToken(void) {
|
Token* PeekToken(void) {
|
||||||
return TokensList->content[CurrentToken];
|
return TokensList->content[CurrentToken];
|
||||||
|
}
|
||||||
|
|
||||||
|
void IgnoreParserLine(void) {
|
||||||
|
while(!ParserAtEnd()) {
|
||||||
|
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) break;
|
||||||
|
|
||||||
|
if (PeekToken()->EndOfFile) break;
|
||||||
|
|
||||||
|
AdvanceParser();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user