module repl import token as _ { Token, Tokenizer, TokenType } 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 << ']' } .keyword { s << '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) } }