diff --git a/includes/token.h b/includes/token.h index cf3f5e2..4022b03 100644 --- a/includes/token.h +++ b/includes/token.h @@ -24,9 +24,9 @@ typedef enum { typedef enum { DB, Include, - Byte, - Load, - Store + Byte + // Load, + // Store } Directive; typedef enum { diff --git a/misc/another_test.asm b/misc/another_test.asm index b6aa256..1ab8ad0 100644 --- a/misc/another_test.asm +++ b/misc/another_test.asm @@ -1,6 +1,6 @@ .db MAX_MEM 0xFFFF .db VIDEO_MEM 0xF37F -.db MAX_LENGTH MAX_MEM - MAX_LENGTH +;.db MAX_LENGTH MAX_MEM - MAX_LENGTH .db MSG "Hello, World!", 0 _start: @@ -9,7 +9,7 @@ _start: call strlen copy r1, MSG cmp r2, 0 - je _end + jz _end cmp r2, MAX_LENGTH jg _end draw_loop: @@ -18,7 +18,7 @@ draw_loop: inc r8 dec r2 cmp r2, 0 - je _end + jz _end jmp draw_loop _end: jmp _end @@ -28,12 +28,14 @@ _end: ; Returns: R2 - Contains the length of the string strlen: copy r2, 0 ; length - cmp [r1], 0 - je end ;The string is zero length + copy byte r4, [r1] + cmp r3, 0 + jz end ;The string is zero length loop: inc r1 - cmp [r1], 0 - je end + copy byte r3, [r1] + cmp r3, 0 + jz end inc r2 jmp loop end: diff --git a/misc/test.asm b/misc/test.asm index 8ab0a53..404bdc3 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -4,11 +4,10 @@ .db msg "Hello, world!", 0 .db NOTERM "No terminating byte here" .db null_byte 0 - +jmp [r4] ;load r2, label something_insance: load r1, unknown_symbol -load byte r1, r3 load r1, 5 .db fun_alright 0x70;does this break? load r3, r4 @@ -23,6 +22,6 @@ inc r1 ;increment r1 xor r1, r1 ;clear self pop r3 jmp unknown_symbol -jmp r4 -jz unknown_symbol +jmp [r4] +jz [r6] ;And a comment at the end \ No newline at end of file diff --git a/src/parser.c b/src/parser.c index 730b836..ae104f2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -108,104 +108,6 @@ void HandleAssemblerDirective() { HeapSize += symbol->Length; } break; - case Load: - { - AdvanceParser(); - Token* reg = PeekToken(); - - if (reg->Class != RegisterClass && reg->Class != DirectiveClass) { - fprintf(stderr, "[Line %d] Syntax error, expected register or keyword 'byte'.\n", reg->LineNumber); - exit(1); - } - - if (reg->Class == RegisterClass) { - AdvanceParser(); - - ExpectPuncuation(Comma, ForwardParser); - - if (PeekToken()->Class != IdentifierClass && PeekToken()->Class != NumberClass && PeekToken()->Class != RegisterClass) { - fprintf(stderr, "[Line %d] Syntax error, expected either a symbol, numeric literal or a register.\n", PeekToken()->LineNumber); - exit(2); - } - - if (PeekToken()->Class == NumberClass) { - directive->Class = MnemonicClass; - directive->Value.Mnemonic = COPYI; - directive->Lemexe = "copyi"; - AdvanceParser(); //Number, register or identifier - } - else if (PeekToken()->Class == RegisterClass) { - directive->Class = MnemonicClass; - directive->Value.Mnemonic = COPY; - directive->Lemexe = "copy"; - AdvanceParser(); //Number, register or identifier - } - else { - ExpectIdentifier(0, ForwardParser); - - directive->Class = MnemonicClass; - directive->Value.Mnemonic = COPYA; - directive->Lemexe = "copya"; - } - } - // else if (reg->Class == DirectiveClass) { - // if (reg->Value.Directive != Byte) { - // fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", reg->LineNumber); - // exit(3); - // } - - // RemoveCurrentToken(); //byte - - // ExpectRegister(); - - // ExpectPuncuation(Comma, ForwardParser); - - // ExpectRegister(); - - // directive->Class = MnemonicClass; - // directive->Value.Mnemonic = LODB; - // directive->Lemexe = "LODB"; - // } - - ExpectLineEndOrFileEnd(ForwardParser); - } - - break; - case Store: - { - AdvanceParser(); - - Token* next = PeekToken(); - - if (next->Class != DirectiveClass) { - //If the token after the current one is invalid then the expect function ahead will exit, so we can - //go ahead and change the STORE directive into a proper opcode here. - directive->Value.Mnemonic = COPY; - directive->Class = MnemonicClass; - directive->Lemexe = "copy"; - } - else { - if (next->Value.Directive != Byte) { - fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", next->LineNumber); - exit(10); - } - - RemoveCurrentToken(); //Remove byte modifier token. - - directive->Value.Mnemonic = COPYB; - directive->Class = MnemonicClass; - directive->Lemexe = "copyb"; - } - - ExpectRegister(); - - ExpectPuncuation(Comma, ForwardParser); - - ExpectRegister(); - - ExpectLineEndOrFileEnd(ForwardParser); - } - break; default: fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe); exit(1); @@ -218,6 +120,86 @@ void HandleOpcode(void) { AdvanceParser(); switch(opcode->Value.Mnemonic) { + case COPY: + { + Token* arg = PeekToken(); + int isByte = 0; + + if (arg->Class == DirectiveClass) { + if (arg->Value.Directive != Byte) { + fprintf(stderr, "Syntax error on line %d: expected keyword 'byte'.\n", opcode->LineNumber); + + exit(1); + } + RemoveCurrentToken(); //byte + + isByte = 1; + + arg = PeekToken(); + } + + if (arg->Class == RegisterClass) { + ExpectRegister(); + + ExpectPuncuation(Comma, ForwardParser); + + arg = PeekToken(); + + if (arg->Class == NumberClass) { + opcode->Value.Mnemonic = isByte ? COPYB : COPYI; + opcode->Lemexe = isByte ? "copyb" : "copyi"; + + AdvanceParser(); + } + else if (arg->Class == RegisterClass) { + if (isByte) { + fprintf(stderr, "Syntax error on line %d: unexpected modifier 'Byte' for Register to Register copy.\n", opcode->LineNumber); + + exit(1); + } + + ExpectRegister(); + + opcode->Value.Mnemonic = COPY; + opcode->Lemexe = "copy"; + } + else if (arg->Class & IdentifierClass) { + opcode->Value.Mnemonic = isByte ? COPYAB : COPYA; + opcode->Lemexe = isByte ? "copyab" : "copya"; + + AdvanceParser(); + } + else { + ExpectPuncuation(LBracket, ForwardParser); + + ExpectRegister(); + + ExpectPuncuation(RBracket, ForwardParser); + + opcode->Value.Mnemonic = isByte ? COPYRAB : COPYRA; + opcode->Lemexe = isByte ? "copyrab" : "copyra"; + } + } + else { + ExpectPuncuation(LBracket, ForwardParser); + + ExpectRegister(); + + ExpectPuncuation(RBracket, ForwardParser); + + ExpectPuncuation(Comma, ForwardParser); + + ExpectPuncuation(LBracket, ForwardParser); + + ExpectRegister(); + + ExpectPuncuation(RBracket, ForwardParser); + + opcode->Value.Mnemonic = isByte ? COPYRARAB : COPYRARA; + opcode->Lemexe = isByte ? "copyrarab" : "copyrara"; + } + } + break; case CMP: { ExpectRegister(); @@ -226,7 +208,7 @@ void HandleOpcode(void) { TokenClass class = PeekToken()->Class; - if (class == NumberClass) { + if (class == NumberClass || class & IdentifierClass) { opcode->Value.Mnemonic = CMPI; opcode->Lemexe = "CMPI"; @@ -272,55 +254,59 @@ void HandleOpcode(void) { { Token* arg = PeekToken(); - opcode->Value.Mnemonic = JMPI; - opcode->Lemexe = "jmpi"; - - if (arg->Class == IdentifierClass) { + if (arg->Class & IdentifierClass) { ExpectIdentifier(0, ForwardParser); opcode->Value.Mnemonic = JMP; opcode->Lemexe = "jmp"; } - else ExpectRegister(); + else + { + ExpectPuncuation(LBracket, ForwardParser); + + ExpectRegister(); + + ExpectPuncuation(RBracket, ForwardParser); + + opcode->Value.Mnemonic = JMPI; + opcode->Lemexe = "jmpi"; + } } break; case JZ: { - Token* arg = PeekToken(); + ExpectIdentifier(0, ForwardParser); - if (arg->Class == IdentifierClass) { - ExpectIdentifier(0, ForwardParser); - - opcode->Value.Mnemonic = JZ; - opcode->Lemexe = "jz"; - } - else ExpectRegister(); + opcode->Value.Mnemonic = JZ; + opcode->Lemexe = "jz"; } break; case JG: { - Token* arg = PeekToken(); - - if (arg->Class == IdentifierClass) { - ExpectIdentifier(0, ForwardParser); - - opcode->Value.Mnemonic = JG; - opcode->Lemexe = "jg"; - } - else ExpectRegister(); + ExpectIdentifier(0, ForwardParser); + opcode->Value.Mnemonic = JG; + opcode->Lemexe = "jg"; } break; case JL: + { + ExpectIdentifier(0, ForwardParser); + + opcode->Value.Mnemonic = JL; + opcode->Lemexe = "jl"; + } + break; + case CALL: { Token* arg = PeekToken(); - if (arg->Class == IdentifierClass) { - ExpectIdentifier(0, ForwardParser); + if ((arg->Class & IdentifierClass) == 0) { + fprintf(stderr, "Syntax error on line %d: expected subroutine call target.\n", opcode->LineNumber); - opcode->Value.Mnemonic = JL; - opcode->Lemexe = "jl"; + exit(1); } - else ExpectRegister(); + + ExpectIdentifier(0, ForwardParser); } break; default: diff --git a/src/scanner.c b/src/scanner.c index c2b1a26..8ba6286 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -283,14 +283,14 @@ Token* ParseIdentifier(void) { return token; } - if (strcmp(lexeme, "load") == 0) { - Token* token = CreateToken(Line, DirectiveClass); + // if (strcmp(lexeme, "load") == 0) { + // Token* token = CreateToken(Line, DirectiveClass); - token->Lemexe = lexeme; - token->Value.Directive = Load; + // token->Lemexe = lexeme; + // token->Value.Directive = Load; - return token; - } + // return token; + // } if (strcmp(lexeme, "byte") == 0) { Token* token = CreateToken(Line, DirectiveClass); @@ -299,14 +299,14 @@ Token* ParseIdentifier(void) { return token; } - if (strcmp(lexeme, "store") == 0) { - Token* token = CreateToken(Line, DirectiveClass); + // if (strcmp(lexeme, "store") == 0) { + // Token* token = CreateToken(Line, DirectiveClass); - token->Lemexe = lexeme; - token->Value.Directive = Store; + // token->Lemexe = lexeme; + // token->Value.Directive = Store; - return token; - } + // return token; + // } Token* token = CreateToken(Line, IdentifierClass);