-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathexp_lang_repl.cr
76 lines (61 loc) · 1.7 KB
/
exp_lang_repl.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
require "readline"
require "./xlexer"
require "./xast"
require "./xscope"
require "../../src/cltk/macros"
require "../../src/cltk/parser/type"
require "../../src/cltk/parser/parser_concern"
insert_output_of() do
module CLTK
alias TokenValue = (String|Int32|Float64)?
end
require "../../src/cltk/parser/crystalize"
require "./xparser"
EXP_LANG::Parser.crystalize
end
lexer = EXP_LANG::Lexer
parser = EXP_LANG::Parser
scope = EXP_LANG::Scope(Expression).new
input = ""
puts "\n\n" +
" welcome to the example repl, exit with: 'exit' \n" +
"--------------------------------------------------\n\n"
while true
begin
# read input
input = Readline.readline(":: ", true) || ""
# exit on exit
exit if input == "exit"
# lex input
tokens = lexer.lex(input)
# parse lexed tokens
res = parser.parse(tokens, {accept: :first}).as(CLTK::ASTNode)
# evaluate the result with a given scope
# (scope my be altered by the expression)
evaluated = res.eval_scope(scope).to_s
# output result of evaluation
puts evaluated
rescue e: CLTK::Lexer::Exceptions::LexingError
show_lexing_error(e, input)
rescue e: CLTK::NotInLanguage
show_syntax_error(e,input)
rescue e
puts e
end
end
def show_lexing_error(e, input)
puts "Lexing error at:\n\n"
puts " " + input.split("\n")[e.line_number-1]
puts " " + e.line_offset.times().map { "-" }.join + "^"
puts e
end
def show_syntax_error(e,input)
pos = e.current.position
if pos
puts "Syntax error at:"
puts " " + input.split("\n")[pos.line_number-1]
puts " " + pos.line_offset.times().map { "-" }.join + "^"
else
puts "invalid input: #{input}"
end
end