mirror of
https://github.com/vonhyou/lisp-interpreter.git
synced 2025-06-08 02:02:01 +00:00
simplify
This commit is contained in:
parent
94599c5e4a
commit
efd5b22761
1 changed files with 31 additions and 39 deletions
70
minlisp.rb
70
minlisp.rb
|
@ -15,9 +15,7 @@ end
|
||||||
|
|
||||||
def tokenize(program)
|
def tokenize(program)
|
||||||
# Convert scripts to token lists
|
# Convert scripts to token lists
|
||||||
replacements = { '(' => ' ( ', ')' => ' ) ' }
|
program.gsub('(', ' ( ').gsub(')', ' ) ').split
|
||||||
program.gsub(Regexp.union(replacements.keys), replacements)
|
|
||||||
.split(' ')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_list(tokens)
|
def make_list(tokens)
|
||||||
|
@ -31,8 +29,7 @@ def read_tokens(tokens)
|
||||||
# read expressions from token
|
# read expressions from token
|
||||||
raise SyntaxError, 'Unexpected EOF' if tokens.empty?
|
raise SyntaxError, 'Unexpected EOF' if tokens.empty?
|
||||||
|
|
||||||
token = tokens.shift
|
case token = tokens.shift
|
||||||
case token
|
|
||||||
when '('
|
when '('
|
||||||
make_list tokens
|
make_list tokens
|
||||||
when ')'
|
when ')'
|
||||||
|
@ -44,41 +41,37 @@ end
|
||||||
|
|
||||||
def atom(token)
|
def atom(token)
|
||||||
# Analyse numbers and symbols
|
# Analyse numbers and symbols
|
||||||
is_integer = ->(atom) { atom.match?(/^-?\d+$/) }
|
case token
|
||||||
is_float = ->(atom) { atom.match?(/^(-?\d+)(\.\d+)?$/) }
|
when /\d/
|
||||||
return Integer token if is_integer.call token
|
(token.to_f % 1).positive? ? token.to_f : token.to_i
|
||||||
return Float token if is_float.call token
|
else
|
||||||
|
token.to_sym
|
||||||
token.to_sym
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##### Environments
|
##### Environments
|
||||||
|
|
||||||
def generate_env
|
$global_env = {
|
||||||
lisp_env = {
|
'+': ->(args) { args.sum }, # args.inject(0, :+)
|
||||||
'+': ->(args) { args.sum }, # args.inject(0, :+)
|
'-': ->(*args) { eval args.join('-') },
|
||||||
'-': ->(*args) { eval args.join('-') },
|
'*': ->(*args) { eval args.join('*') },
|
||||||
'*': ->(*args) { eval args.join('*') },
|
'/': ->(*args) { eval args.join('/') },
|
||||||
'/': ->(*args) { eval args.join('/') },
|
'>': ->(args) { args[0] > args[1] },
|
||||||
'>': ->(args) { args[0] > args[1] },
|
'<': ->(args) { args[0] < args[1] },
|
||||||
'<': ->(args) { args[0] < args[1] },
|
'=': ->(args) { args[0] == args[1] },
|
||||||
'=': ->(args) { args[0] == args[1] },
|
'>=': ->(args) { args[0] >= args[1] },
|
||||||
'>=': ->(args) { args[0] >= args[1] },
|
'<=': ->(args) { args[0] <= args[1] },
|
||||||
'<=': ->(args) { args[0] <= args[1] },
|
'min': ->(*args) { args.min },
|
||||||
'min': ->(*args) { args.min },
|
'max': ->(*args) { args.max },
|
||||||
'max': ->(*args) { args.max },
|
'car': ->(arr) { arr[0] },
|
||||||
'car': ->(arr) { arr[0] },
|
'cdr': ->(arr) { arr[1..-1] },
|
||||||
'cdr': ->(arr) { arr[1..-1] },
|
'cons': ->(arr) { arr },
|
||||||
'cons': ->(arr) { arr },
|
'quote': ->(arr) { arr },
|
||||||
'quote': ->(arr) { arr },
|
'print': ->(arg) { p arg },
|
||||||
'print': ->(arg) { p arg },
|
'begin': ->(*_args) { true }
|
||||||
'begin': ->(*_args) { true }
|
}
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
##### Lisp Eval
|
##### Lisp Eval
|
||||||
|
|
||||||
$global_env = generate_env
|
|
||||||
def lisp_eval(elem, env = $global_env)
|
def lisp_eval(elem, env = $global_env)
|
||||||
if elem.instance_of? Symbol
|
if elem.instance_of? Symbol
|
||||||
env[elem]
|
env[elem]
|
||||||
|
@ -103,18 +96,17 @@ def lisp_eval(elem, env = $global_env)
|
||||||
end
|
end
|
||||||
|
|
||||||
##### REPL
|
##### REPL
|
||||||
|
def repl(prompt = 'minlisp ƛ>> ')
|
||||||
def repl(prompt='minlisp ƛ>> ')
|
|
||||||
loop do
|
loop do
|
||||||
print prompt
|
print prompt
|
||||||
val = lisp_eval(parse(gets.chomp))
|
val = lisp_eval(parse(gets.chomp))
|
||||||
|
|
||||||
print_value val unless val.nil?
|
print_value val unless val.nil? || val.instance_of?(Proc)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def print_value(value)
|
def print_value(value)
|
||||||
puts ";Value: #{value.to_s}"
|
puts ";Value: #{value}"
|
||||||
end
|
end
|
||||||
|
|
||||||
repl()
|
repl
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue