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"
|
||||
|
||||
void Disassemble(unsigned char image[HIGHMEMORY]);
|
||||
//void Disassemble(unsigned char image[HIGHMEMORY]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef struct {
|
||||
Mnemonic Mnemonic;
|
||||
OpcodeParameter ParameterOneType;
|
||||
OpcodeParameter ParameterTwoType;
|
||||
int LineNumber;
|
||||
|
||||
union {
|
||||
int Constant;
|
||||
|
||||
+25
-25
@@ -1,27 +1,27 @@
|
||||
;.org 0x100
|
||||
.db video_start 0xF37F
|
||||
.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
|
||||
;copy 2, 45
|
||||
;loop:
|
||||
; cmp r1, 0
|
||||
; jz loop
|
||||
; add r1, 1
|
||||
;mov r1, 5 ; move the immediate value 5 into r1
|
||||
;add r1,5 ; add 5 into r1
|
||||
;int 21 ; maybe that will call some string drawing BIOS-like routine
|
||||
;ret
|
||||
; 4 byte header
|
||||
; | Address of First Opcode (2 bytes) | End of Binary (2 bytes) |
|
||||
load r1, [msg] ; Because the lod* instructions can't load an address
|
||||
; from anything but a register, this becomes laa r1, [msg]
|
||||
|
||||
;Routine: string_length
|
||||
;In: String address in r1
|
||||
;Out: Length in R2
|
||||
|
||||
string_length:
|
||||
loadb r3, [r1] ; Load the byte from the address in R1, into R3
|
||||
load r2, 0 ; String length
|
||||
cmp r3, 0 ; Is R3 a null byte?
|
||||
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);
|
||||
void GetParameter(unsigned char instruction, char* text);
|
||||
|
||||
/*
|
||||
void Disassemble(unsigned char image[HIGHMEMORY]) {
|
||||
Image = image;
|
||||
int position = image[0] + image[1];
|
||||
@@ -117,7 +117,7 @@ void Disassemble(unsigned char image[HIGHMEMORY]) {
|
||||
memset(parameter2, '\0', sizeof(char) * 32);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
int IsRegisterPattern(unsigned char pattern, char* lexeme) {
|
||||
if (pattern > 8) {
|
||||
lexeme[0] = '\0';
|
||||
|
||||
+47
-45
@@ -10,19 +10,14 @@ int CurrentToken = 0;
|
||||
//int HeapStart = 4; // zero indexed, used for declared variables.
|
||||
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
|
||||
|
||||
//IROpcode* CreateIROpcode(Mnemonic mnemonic);
|
||||
void PrintSymbols(void);
|
||||
void HandleOperation(void);
|
||||
void HandleAssemblerDirective(void);
|
||||
void AdvanceParser(void);
|
||||
void IgnoreParserLine(void);
|
||||
Token* PeekToken(void);
|
||||
int ParserAtEnd(void);
|
||||
int Expect(int, ...);
|
||||
//List* SymbolsTable;
|
||||
// unsigned int HeapTop = 4;
|
||||
// unsigned int ProgramCounter = 0;
|
||||
// unsigned char Heap[HIGHMEMORY];
|
||||
// unsigned char Memory[HIGHMEMORY];
|
||||
IRState MachineState;
|
||||
|
||||
IRState* ParseTokens(List* tokens) {
|
||||
@@ -40,9 +35,8 @@ IRState* ParseTokens(List* tokens) {
|
||||
Token* t = PeekToken();
|
||||
|
||||
switch(t->Class) {
|
||||
case DirectiveClass:
|
||||
//HandleAssemblerDirective();
|
||||
//while(!ParserAtEnd() && (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != NewLine)) AdvanceParser();
|
||||
case DirectiveClass: //Maybe these should be ignored, let another process handle that.
|
||||
IgnoreParserLine();
|
||||
break;
|
||||
case MnemonicClass:
|
||||
HandleOperation();
|
||||
@@ -50,7 +44,7 @@ IRState* ParseTokens(List* tokens) {
|
||||
case LabelClass:
|
||||
printf("%s: \n", t->Lemexe);
|
||||
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
|
||||
//AddSymbol(t, 2, ProgramCounter, 1);
|
||||
AdvanceParser(); //Consume the NewLine
|
||||
break;
|
||||
default:
|
||||
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();
|
||||
|
||||
while(!ParserAtEnd()) {
|
||||
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
|
||||
break;
|
||||
}
|
||||
|
||||
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();
|
||||
//No parameters here, we have a line break.
|
||||
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
|
||||
goto InsertInstruction;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
AdvanceParser(); //Consume the line break
|
||||
|
||||
free(ins);
|
||||
}
|
||||
|
||||
@@ -651,4 +643,14 @@ int ParserAtEnd(void) {
|
||||
|
||||
Token* PeekToken(void) {
|
||||
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