Merge branch 'trunk' of ssh://src.le-moine.org:38172/gwh/rpl.rb into trunk

This commit is contained in:
Gwenhael Le Moine 2022-02-15 18:48:27 +01:00
commit 42244c7106
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
33 changed files with 150 additions and 118 deletions

View file

@ -2,6 +2,10 @@
https://github.com/louisrubet/rpn/ inspired language in ruby
To run REPL locally: `ruby -Ilib bin/rpl`
To run the test suite: `find ./spec/ -name \*.rb -exec ruby -Ilib {} \;`
# TODO-list
* pseudo filesystem: subdir for variables
* UI toolkit (based on https://github.com/AndyObtiva/glimmer-dsl-libui ?)

51
bin/rpl Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'readline'
require 'rpl'
class RplRepl
def initialize
@interpreter = Rpl.new
end
def run
Readline.completion_proc = proc do |s|
( @interpreter.dictionary.words.keys + @interpreter.dictionary.vars.keys ).grep(/^#{Regexp.escape(s)}/)
end
Readline.completion_append_character = ' '
loop do
input = Readline.readline( ' ', true )
break if input.nil? || input == 'quit'
pp Readline::HISTORY if input == 'history'
# Remove blank lines from history
Readline::HISTORY.pop if input.empty?
begin
@interpreter.run( input )
rescue ArgumentError => e
p e
end
print_stack
end
end
def format_element( elt )
@interpreter.stringify( elt )
end
def print_stack
stack_size = @interpreter.stack.size
@interpreter.stack.each_with_index do |elt, i|
puts "#{stack_size - i}: #{format_element( elt )}"
end
end
end
RplRepl.new.run

43
lib/rpl.rb Normal file
View file

@ -0,0 +1,43 @@
# frozen_string_literal: true
require 'rpl/interpreter'
require 'rpl/core/branch'
require 'rpl/core/general'
require 'rpl/core/mode'
require 'rpl/core/operations'
require 'rpl/core/program'
require 'rpl/core/stack'
require 'rpl/core/store'
require 'rpl/core/string'
require 'rpl/core/test'
require 'rpl/core/time-date'
require 'rpl/core/trig'
require 'rpl/core/logarithm'
require 'rpl/core/filesystem'
require 'rpl/core/list'
class Rpl < Interpreter
def initialize( stack = [], dictionary = Dictionary.new )
super
populate_dictionary if @dictionary.words.empty?
end
prepend RplLang::Core::Branch
prepend RplLang::Core::FileSystem
prepend RplLang::Core::General
prepend RplLang::Core::List
prepend RplLang::Core::Logarithm
prepend RplLang::Core::Mode
prepend RplLang::Core::Operations
prepend RplLang::Core::Program
prepend RplLang::Core::Stack
prepend RplLang::Core::Store
prepend RplLang::Core::String
prepend RplLang::Core::Test
prepend RplLang::Core::TimeAndDate
prepend RplLang::Core::Trig
def populate_dictionary; end
end

View file

@ -34,8 +34,7 @@ module RplLang
run( args[1][:value] )
end
end ) # specific
end )
@dictionary.add_word( ['loop'],
'Branch',
@ -49,7 +48,7 @@ module RplLang
run( args[2][:value] )
end
end ) # specific
end )
end
end
end

View file

@ -6,8 +6,6 @@ module RplLang
def populate_dictionary
super
# Mode
@dictionary.add_word( ['prec'],
'Mode',
'( a -- ) set precision to a',

View file

@ -385,7 +385,6 @@ module RplLang
# proc do
# end )
end
end
end

View file

@ -124,7 +124,6 @@ module RplLang
end
@stack << args[0]
end )
@dictionary.add_word( ['rolld'],

View file

@ -60,7 +60,6 @@ module RplLang
« swap »
ift
over rcl + swap sto' )
end )
@dictionary.add_word( ['sto-'],
@ -83,7 +82,6 @@ module RplLang
« swap »
ift
over rcl * swap sto' )
end )
@dictionary.add_word( ['sto÷', 'sto/'],
@ -95,7 +93,6 @@ module RplLang
« swap »
ift
over rcl swap / swap sto' )
end )
@dictionary.add_word( ['sneg'],

View file

@ -95,7 +95,7 @@ module RplLang
end
@stack << result
end ) # specific
end )
@dictionary.add_word( ['split'],
'String',
@ -107,7 +107,7 @@ module RplLang
@stack << { type: :string,
value: elt }
end
end ) # specific
end )
end
end
end

View file

@ -112,7 +112,7 @@ module RplLang
proc do
@stack << { type: :boolean,
value: true }
end ) # specific
end )
@dictionary.add_word( ['false'],
'Test',
@ -120,7 +120,7 @@ module RplLang
proc do
@stack << { type: :boolean,
value: false }
end ) # specific
end )
end
end
end

View file

@ -63,7 +63,6 @@ module RplLang
ift
»
ifte' )
end )
@dictionary.add_word( ['tan'],

View file

@ -2,7 +2,7 @@
require 'bigdecimal/math'
require_relative './dictionary'
require 'rpl/dictionary'
class Interpreter
include BigMath

33
rpl.gemspec Normal file
View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
Gem::Specification.new do |s|
s.name = 'rpl'
s.version = '0.1.0'
s.summary = 'Functional Stack Language'
s.description = "A language inspired by HP's RPL and https://github.com/louisrubet/rpn/"
s.authors = ['Gwenhael Le Moine']
s.email = 'gwenhael@le-moine.org'
s.files = ['lib/rpl.rb',
'lib/rpl/dictionary.rb',
'lib/rpl/interpreter.rb',
'lib/rpl/core/branch.rb',
'lib/rpl/core/filesystem.rb',
'lib/rpl/core/general.rb',
'lib/rpl/core/list.rb',
'lib/rpl/core/logarithm.rb',
'lib/rpl/core/mode.rb',
'lib/rpl/core/operations.rb',
'lib/rpl/core/program.rb',
'lib/rpl/core/stack.rb',
'lib/rpl/core/store.rb',
'lib/rpl/core/string.rb',
'lib/rpl/core/test.rb',
'lib/rpl/core/time-date.rb',
'lib/rpl/core/trig.rb']
s.homepage = 'https://github.com/gwenhael-le-moine/rpl.rb'
s.license = 'GPL-3.0'
s.executables << 'rpl'
s.required_ruby_version = '~> 2.7'
end

90
rpl.rb
View file

@ -1,90 +0,0 @@
# frozen_string_literal: true
require 'readline'
require_relative './lib/interpreter'
require_relative './lib/core/branch'
require_relative './lib/core/general'
require_relative './lib/core/mode'
require_relative './lib/core/operations'
require_relative './lib/core/program'
require_relative './lib/core/stack'
require_relative './lib/core/store'
require_relative './lib/core/string'
require_relative './lib/core/test'
require_relative './lib/core/time-date'
require_relative './lib/core/trig'
require_relative './lib/core/logarithm'
require_relative './lib/core/filesystem'
require_relative './lib/core/list'
class Rpl < Interpreter
def initialize( stack = [], dictionary = Dictionary.new )
super
populate_dictionary if @dictionary.words.empty?
end
prepend RplLang::Core::Branch
prepend RplLang::Core::FileSystem
prepend RplLang::Core::General
prepend RplLang::Core::List
prepend RplLang::Core::Logarithm
prepend RplLang::Core::Mode
prepend RplLang::Core::Operations
prepend RplLang::Core::Program
prepend RplLang::Core::Stack
prepend RplLang::Core::Store
prepend RplLang::Core::String
prepend RplLang::Core::Test
prepend RplLang::Core::TimeAndDate
prepend RplLang::Core::Trig
def populate_dictionary; end
end
class RplRepl
def initialize
@interpreter = Rpl.new
end
def run
Readline.completion_proc = proc do |s|
Readline::HISTORY.grep(/^#{Regexp.escape(s)}/)
end
Readline.completion_append_character = ' '
loop do
input = Readline.readline( ' ', true )
break if input.nil? || input == 'quit'
pp Readline::HISTORY if input == 'history'
# Remove blank lines from history
Readline::HISTORY.pop if input.empty?
begin
@interpreter.run( input )
rescue ArgumentError => e
p e
end
print_stack
end
end
def format_element( elt )
@interpreter.stringify( elt )
end
def print_stack
stack_size = @interpreter.stack.size
@interpreter.stack.each_with_index do |elt, i|
puts "#{stack_size - i}: #{format_element( elt )}"
end
end
end
RplRepl.new.run if __FILE__ == $PROGRAM_NAME

View file

@ -2,7 +2,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestParser < Test::Unit::TestCase
def test_stack_extract

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageBranch < Test::Unit::TestCase
def test_loop

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageFileSystem < Test::Unit::TestCase
def test_fread

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TesttLanguageOperations < Test::Unit::TestCase
def test_add

View file

@ -2,7 +2,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageProgram < Test::Unit::TestCase
def test_eval

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageStack < Test::Unit::TestCase
def test_swap

View file

@ -2,7 +2,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageProgram < Test::Unit::TestCase
def test_sto

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageString < Test::Unit::TestCase
def test_to_string

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageTest < Test::Unit::TestCase
def test_greater_than

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestLanguageTimeDate < Test::Unit::TestCase
def test_time

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TesttLanguageOperations < Test::Unit::TestCase
def test_pi

View file

@ -3,7 +3,7 @@
require 'test/unit'
require_relative '../rpl'
require 'rpl'
class TestParser < Test::Unit::TestCase
def test_number