first commit
This commit is contained in:
commit
882f1b637b
5 changed files with 131 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.exe
|
BIN
compiler
Normal file
BIN
compiler
Normal file
Binary file not shown.
124
main.odin
Normal file
124
main.odin
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:log"
|
||||||
|
import "core:os"
|
||||||
|
import "core:strconv"
|
||||||
|
import "core:text/regex"
|
||||||
|
|
||||||
|
String :: struct {
|
||||||
|
value: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
Name :: struct {
|
||||||
|
value: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
Number :: struct {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
Left_Paren :: struct {}
|
||||||
|
Right_Paren :: struct {}
|
||||||
|
Comma :: struct {}
|
||||||
|
|
||||||
|
Token :: union {
|
||||||
|
String,
|
||||||
|
Name,
|
||||||
|
Number,
|
||||||
|
Left_Paren,
|
||||||
|
Right_Paren,
|
||||||
|
Comma,
|
||||||
|
}
|
||||||
|
|
||||||
|
Populator_Proc :: proc(value: string) -> Token
|
||||||
|
|
||||||
|
Token_Desc :: struct {
|
||||||
|
regex_comp: regex.Regular_Expression,
|
||||||
|
populator_proc: Populator_Proc,
|
||||||
|
}
|
||||||
|
|
||||||
|
Tokenizer :: struct {
|
||||||
|
token_descs: [dynamic]Token_Desc,
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer_add_token :: proc(
|
||||||
|
tokenizer: ^Tokenizer,
|
||||||
|
regex_string: string,
|
||||||
|
populator_proc: Populator_Proc,
|
||||||
|
) -> regex.Error {
|
||||||
|
append(
|
||||||
|
&tokenizer.token_descs,
|
||||||
|
Token_Desc{regex_comp = regex.create(regex_string) or_return, populator_proc = populator_proc},
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer_create :: proc() -> (tokenizer: Tokenizer, err: regex.Error) {
|
||||||
|
tokenizer_add_token(&tokenizer, "^\\d+", proc(value: string) -> Token {
|
||||||
|
parsed, _ := strconv.parse_u64(value)
|
||||||
|
return Number{value = parsed}
|
||||||
|
}) or_return
|
||||||
|
|
||||||
|
tokenizer_add_token(&tokenizer, "^\".*?\"", proc(value: string) -> Token {
|
||||||
|
return String{value = value[1:len(value) - 1]}
|
||||||
|
}) or_return
|
||||||
|
|
||||||
|
tokenizer_add_token(&tokenizer, "^\\w+", proc(value: string) -> Token {
|
||||||
|
return Name{value = value}
|
||||||
|
}) or_return
|
||||||
|
|
||||||
|
tokenizer_add_token(&tokenizer, "^\\(", proc(_: string) -> Token {return Left_Paren{}}) or_return
|
||||||
|
tokenizer_add_token(&tokenizer, "^\\)", proc(_: string) -> Token {return Right_Paren{}}) or_return
|
||||||
|
tokenizer_add_token(&tokenizer, "^,", proc(_: string) -> Token {return Comma{}}) or_return
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenize :: proc(tokenizer: Tokenizer, input: string) -> []Token {
|
||||||
|
tokens: [dynamic]Token
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
loop: for true {
|
||||||
|
for reg in tokenizer.token_descs {
|
||||||
|
if i >= len(input) {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
|
||||||
|
capture, matched := regex.match(reg.regex_comp, input[i:])
|
||||||
|
if matched {
|
||||||
|
token := reg.populator_proc(input[i:i + capture.pos[0][1]])
|
||||||
|
append(&tokens, token)
|
||||||
|
i += capture.pos[0][1]
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
context.logger = log.create_console_logger()
|
||||||
|
|
||||||
|
bytes, ok := os.read_entire_file(os.args[1])
|
||||||
|
if !ok {
|
||||||
|
log.fatal("Failed to read file")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
input := string(bytes)
|
||||||
|
|
||||||
|
tokenizer, err := tokenizer_create()
|
||||||
|
if err != nil {
|
||||||
|
log.fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens := tokenize(tokenizer, input)
|
||||||
|
for token in tokens {
|
||||||
|
fmt.println(token)
|
||||||
|
}
|
||||||
|
}
|
5
odinfmt.json
Normal file
5
odinfmt.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"character_width": 110,
|
||||||
|
"tabs": false,
|
||||||
|
"tabs_width": 4
|
||||||
|
}
|
1
test.txt
Normal file
1
test.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
say_hi("bob", 26)
|
Loading…
Add table
Reference in a new issue