Skip to content

Commit

Permalink
Self-Hosted Number Token matching working
Browse files Browse the repository at this point in the history
  • Loading branch information
Letsmoe committed Mar 6, 2024
1 parent 9300937 commit 338e1f3
Show file tree
Hide file tree
Showing 14 changed files with 751 additions and 1,712 deletions.
59 changes: 59 additions & 0 deletions cascade.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

argv=("$@")
len=${#argv[@]}

if [ $len -lt 2 ]; then
echo "Usage: ./cascade.bash <compiler> [metafiles...]"
exit 1
fi

compile() {
nasm -F dwarf -g -f elf32 -i ./assembly -o $1.o $1.asm
ld -m elf_i386 -o $1.bin $1.o
rm $1.o
}

while inotifywait -e close_write ${argv[*]} >/dev/null 2>&1; do
# Iterate over all files and compile them.
# The last element (n - 1) is always the compiler and the current is the input.
clear;
for (( i=1; i<$len; i++ )); do
compiler=${argv[$i - 1]}
metafile=${argv[$i]}

if (( $i == $len - 1 )); then
# clear;
OUTPUT=$($compiler ${argv[$i]})
if [ $? -gt 0 ]; then
echo "$OUTPUT"
echo "Run failed"
break 1
else
echo "$OUTPUT"
echo "$(date) Compilation successful"
fi
else
compiler_output=$($compiler $metafile)

if [ $? -gt 0 ]; then
echo "$compiler_output"
echo "$(date) Run failed - reverting changes"
break 1
fi

echo "$compiler_output" > "$metafile.asm"

compile $metafile;
argv[$i]="$metafile.bin"

if [ $? == 0 ]; then
echo "$compiler_output"
echo "$(date) Compilation successful"
else
echo "Compilation failed"
break 1
fi
fi
done
done
1 change: 0 additions & 1 deletion lib/asm_macros.asm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
section .data
pflag db 0
tflag db 0
; Error Flag, indicates a parsing error which may be recovered from
; by backtracking
Expand Down
65 changes: 52 additions & 13 deletions lib/char-test.asm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
; Output:
; eax - 1 if the current char is greater or equal to `edi`, 0 otherwise
test_char_greater_equal:
call input_blanks
push edx
mov edx, input_string
add edx, [input_string_offset]
Expand All @@ -17,12 +16,10 @@ test_char_greater_equal:

; if the current char is less than `edi`, return 0
mov byte [eswitch], 1
mov byte [pflag], 0
jmp .done
.greater_equal:
; if the current char is greater or equal to `edi`, return 1
mov byte [eswitch], 0
mov byte [pflag], 1
.done:
pop edx
ret
Expand All @@ -33,7 +30,6 @@ test_char_greater_equal:
; Output:
; eax - 1 if the current char is less or equal to `edi`, 0 otherwise
test_char_less_equal:
call input_blanks
push edx
mov edx, input_string
add edx, [input_string_offset]
Expand All @@ -46,30 +42,61 @@ test_char_less_equal:

; if the current char is greater than `edi`, return 0
mov byte [eswitch], 1
mov byte [pflag], 0
jmp .done
.less_equal:
; if the current char is less or equal to `edi`, return 1
mov byte [eswitch], 0
mov byte [pflag], 1
.done:
pop edx
ret

; Tests whether the current char in `input_string` is equal to `edi`
; Inputs
; edi - the character to compare to
; Output:
; eax - 1 if the current char is less or equal to `edi`, 0 otherwise
test_char_equal:
push edx
mov edx, input_string
add edx, [input_string_offset]

xor eax, eax
mov al, byte [edx]

cmp eax, edi
je .equal

; if the current char is greater than `edi`, return 0
mov byte [eswitch], 1
jmp .done
.equal:
; if the current char is less or equal to `edi`, return 1
mov byte [eswitch], 0
.done:
pop edx
ret


; If the parse flag is set to 1 it will scan the input character
; If the token flag is set to 1 it will add the character to the token
; Inputs:
; edi - the character to compare to
; Outputs:
; - none
; Implements following method:
; if (flag) {
; // if taking token, add to token
; if (tokenflag) token = token + inbuf.charAt(inp) ;
; // scan the character
; inp++ ;
; };
scan_or_parse:
call input_blanks
; If the parse flag is not set we encountered an error during parsing.
; we're done here...
cmp byte [pflag], 1
jne .done
cmp byte [eswitch], 1
je .done
cmp byte [tflag], 1
jne .done_error
jne .done

; if the token flag is set, add the character to the token
push edx
Expand All @@ -92,8 +119,20 @@ scan_or_parse:
add word [input_string_offset], 1
pop edx
mov byte [eswitch], 0
ret
.done:
ret
.done_error:
mov byte [eswitch], 1
ret

; Clears the last_match variable to all zeros
clear_token:
push edx
mov edx, last_match
.loop:
cmp byte [edx], 0
je .done
mov byte [edx], 0
inc edx
jmp .loop
.done:
pop edx
ret
2 changes: 1 addition & 1 deletion lib/hash-map.asm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ one_at_a_time:
xor eax, ebx ; hash ^= hash >> 6
inc ecx ; i++
jmp .loop
.done
.done:
mov ebx, eax
shl ebx, 3
add eax, ebx ; hash += hash << 3
Expand Down
Binary file removed meta/backup/meta.output.asm.bin
Binary file not shown.
File renamed without changes.
68 changes: 38 additions & 30 deletions meta/meta.input.meta
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ PROGRAM =
->("int 0x80")
$(DEFINITION | INCLUDE_STATEMENT | COMMENT))) ".END";

INCLUDE_STATEMENT = ".INCLUDE" .STRING_RAW ";" .DIRECT("mov esi, last_match") .DIRECT("call import_meta_file_mm32") .DIRECT("mov byte [eswitch], 0");
// -------------------------------- Includes -----------------------------------

DATA_TYPE = (("{"
.LABEL("section .bss")
.NUMBER ->(% " resb " *) "}")
| (.STRING .LABEL("section .data") ->(% " db " * ", 0x00"))
| (.NUMBER .LABEL("section .data") ->(% " dd " *)));
INCLUDE_STATEMENT = ".INCLUDE" .STRING_RAW ";"
.DIRECT("mov esi, last_match")
.DIRECT("call import_meta_file_mm32")
.DIRECT("mov byte [eswitch], 0");

// --------------------------------- Output ------------------------------------

OUT1 = "*1" ->("call gn1")
| "*2" ->("call gn2")
Expand All @@ -37,7 +38,7 @@ OUT1 = "*1" ->("call gn1")
| "%" ->("mov edi, str_vector_8192")
->("call vector_pop_string")
->("call print_mm32")
| .STRING ->("print " *);
| STRING ->("print " *);

OUT_IMMEDIATE = .STRING_RAW ->(*);

Expand All @@ -47,13 +48,10 @@ OUTPUT = ("->" "(" $(OUT1) ")" ->("call newline")
| ".DIRECT" "(" $ OUT_IMMEDIATE ")";

EX3 = .ID ->("call vstack_clear") ->("call " *) ->("call vstack_restore")
| .STRING ->("test_input_string " *)
| ".ID" ->("call test_for_id")
| ".RET" ->("ret")
| ".NOT" (.STRING | .NUMBER) ->("match_not " *)
| ".NUMBER" ->("call test_for_number")
| ".NOT" (STRING | NUMBER) ->("match_not " *)
| ".STRING_RAW" ->("call test_for_string_raw")
| ".STRING" ->("call test_for_string")
| "%>"
->("mov edi, str_vector_8192")
->("mov esi, last_match")
Expand All @@ -62,7 +60,8 @@ EX3 = .ID ->("call vstack_clear") ->("call " *) ->("call vstack_restore")
| ".EMPTY" ->("mov byte [eswitch], 0")
| "$" .LABEL(*1 ":") EX3
->("cmp byte [eswitch], 0")
->("je " *1) ->("mov byte [eswitch], 0")
->("je " *1)
->("mov byte [eswitch], 0")
| "{" EX1 $("|" EX1) "}"
| COMMENT;

Expand All @@ -83,58 +82,67 @@ DEFINITION = .ID .LABEL(* ":") "=" EX1 ";" ->("ret");
TOKEN_DEFINITION = .ID
.LABEL(* ":") ":" TX1 ";" ->("ret");

TX1 = TX2 $("|" ->("je T" *1) TX2)
.LABEL("T" *1 ":") ;
TX1 = TX2 $("|"
->("cmp byte [eswitch], 0")
->("je " *1) TX2)
.LABEL(*1 ":") ;

TX2 = TX3
->("cmp byte [eswitch], 1")
->("je T" *1)
// Return from rule if parse flag = 0
->("je " *1)
// Return from rule if error switch = 1
$(TX3
->("cmp byte [pflag], 0")
->("jne T" *1))
.LABEL("T" *1 ":");
->("cmp byte [eswitch], 1")
->("je " *1))
.LABEL(*1 ":");

TX3 = (".TOKEN"
// Capture the incoming token
->("mov byte [tflag], 1")
->("call clear_token")
| ".DELTOK"
// Stop capturing the token
->("mov byte [tflag], 0")
| "$" .LABEL("T" *1 ":") TX3
->("je T" *1))
| "$" .LABEL(*1 ":") TX3
->("cmp byte [eswitch], 0")
->("je " *1))
->("mov byte [eswitch], 0")
| ".ANYBUT(" CX1 ")"
->("NOT" "scan_or_parse")
| ".ANY(" CX1 ")"
->("call scan_or_parse")
| .ID
->("CLL " *)
->("call " *)
| "(" TX1 ")";

CX1 = CX2 $("!"
->("je C" *1) CX2)
.LABEL("C" *1 ":");
->("je " *1) CX2)
.LABEL(*1 ":");

CX2 = CX3 (":"
->("mov edi, " *)
->("call test_char_greater_equal")
->("cmp byte [pflag], 1")
->("jne D" *1)
->("cmp byte [eswitch], 0")
->("jne " *1)
CX3
->("mov edi, " *)
->("call test_char_less_equal")
.LABEL("D" *1 ":")
| .EMPTY ->("CE " *));
.LABEL(*1 ":")
| .EMPTY
->("mov edi, " *)
->("call test_char_equal"));

CX3 = .NUMBER;
CX3 = NUMBER;

// -------------------------------- Comments -----------------------------------

COMMENT = "//" .NOT 10;

.TOKENS

PREFIX : .TOKEN $.ANY(65:90) .DELTOK;
PREFIX : $.ANY(32!9!13!10);
NUMBER : PREFIX .TOKEN DIGIT $DIGIT .DELTOK;
DIGIT : .ANY(48:57);
STRING : PREFIX .ANY(34) .TOKEN $.ANYBUT(13!10!34) .DELTOK .ANY(34) ;

.END
Loading

0 comments on commit 338e1f3

Please sign in to comment.