97 lines
1.8 KiB
V
97 lines
1.8 KiB
V
module repl
|
|
|
|
import tokenizer as _ { Token, Tokenizer, VuaToken }
|
|
import readline { read_line }
|
|
|
|
pub struct Repl {
|
|
pub:
|
|
welcome_msg string = "Welcome to the REPL!"
|
|
}
|
|
|
|
/**
|
|
* Caller owns returned memory.
|
|
*/
|
|
pub fn (r Repl) read(input string) ![]Token {
|
|
mut tokens := []Token{
|
|
len: 0,
|
|
cap: 128,
|
|
init: Token{0, .eof},
|
|
}
|
|
mut tokenizer := Tokenizer{input: input}
|
|
|
|
for !tokenizer.end_of_input() {
|
|
token := tokenizer.parse_all()!
|
|
if token.tag == .eof { break }
|
|
if token.tag == .newline {
|
|
if tokens.len > 0 {
|
|
break
|
|
} else {
|
|
continue // skip empty lines
|
|
}
|
|
}
|
|
tokens << token
|
|
}
|
|
|
|
if tokens.len == 0 {
|
|
return error('No input whatsoever')
|
|
}
|
|
|
|
return tokens
|
|
}
|
|
|
|
pub fn (r Repl) eval(ast []Token, input string) string {
|
|
mut s := []string{len: 0, cap: 4096, init: ''}
|
|
|
|
for token in ast {
|
|
s << ', '
|
|
match token.tag {
|
|
.eof { s << 'EOF' }
|
|
.nil { s << 'nil' }
|
|
.string { s << 'string' }
|
|
.number { s << 'number' }
|
|
.decimal { s << 'decimal' }
|
|
.true { s << 'true' }
|
|
.false { s << 'false' }
|
|
.table_start { s << '{' }
|
|
.table_end { s << '}' }
|
|
.identifier { s << 'identifier' }
|
|
.comma { s << ',' }
|
|
.newline { s << '\n' }
|
|
.equal { s << '=' }
|
|
.dot { s << '.' }
|
|
.angle_bracket_left { s << '[' }
|
|
.angle_bracket_right { s << ']' }
|
|
.reserved_keyword { s << 'reserved_keyword' }
|
|
.operator, .operator_len2, .operator_len3{ s << 'operator' }
|
|
}
|
|
}
|
|
|
|
if s.len == 0 {
|
|
return 'No output'
|
|
}
|
|
|
|
return s.join(' ')
|
|
}
|
|
|
|
//fn (r Repl) print(t VuaType) {
|
|
pub fn (r Repl) print(t string) string {
|
|
return t
|
|
}
|
|
|
|
pub fn (r Repl) loop() ! {
|
|
for {
|
|
input := read_line('vua>> ') or {
|
|
println('\nGoodbye')
|
|
break
|
|
}
|
|
if input.trim_space() == 'exit' {
|
|
println('\nGoodbye')
|
|
break
|
|
}
|
|
tokens := r.read(input.str())!
|
|
expr := r.eval(tokens, input.str())
|
|
output := r.print(expr)
|
|
println(output)
|
|
}
|
|
}
|