- is an interpreter for Scheme, a Lisp dialect with exceptionally clear and concise semantics and a focus on functional programming
- provides a SAP GUI based workbench for Scheme
- is written in, and can be called from ABAP
The code can be cloned with ABAP GIT.
- The main version is developed on Netweaver 7.5 and should work on ABAP Netweaver 7.4.
- Milestones are downported to other branches (7.02).
- The legacy code on SCN Code Gallery should work on older releases.
To check your installation, execute this guess my number game...
(begin (display "Please enter a number between 1 - 100: ")
(do ((quit #f)
(guess 0)
(answer (+ 1 (random 100))) )
(quit)
(begin (set! guess (read)) (display guess) )
(cond ((and (number? guess) (< guess answer)) (display "\nToo low. Please guess again: ") )
((and (number? guess) (> guess answer)) (display "\nToo high. Please guess again: ") )
(else (set! quit #t) (if (number? guess) (display "\nCorrect!")
(display "\nGood bye...") ) ) ) ) )
Scheme syntax is based upon nested parenthesization. The wiki pages are a good place to start.
- I suggest you check the syntax and understand Lists.
- For questions/comments/bugs/feature requests/wishes please create an issue
- How to enable the new editor
- Scheme is one of the main Lisp dialects, alongside Common Lisp and Clojure. Conrad Barski's Land of Lisp, Martin Ceronio's LISP interpreter in ABAP and Peter Norvig inspired me to learn Lisp. It is common to Make your own Lisp to really understand Lisp's core concepts.
-
Scheme's uses symbolic expressions (S-exps) to represent code and data. Expressions are then evaluated. Those concepts cannot be expressed in ABAP, except by first implementing a Lisp interpreter in ABAP (Greenspun 10th rule ).
-
My initial plan was to write a Lisp workbench for Martin's Lisp interpreter. I changed the target language after reading the Revised 7 Report on the Algorithmic Language Scheme aka R7RS small that offers a lot of examples to verify the interpreter. With this I can aim at compatibility with open source Scheme code.
-
In constrast to ABAP, Scheme has a very small number of rules for forming expressions that can be composed without restrictions. Scheme is lexically scoped and requires proper tail call optimization. Scheme is apt at symbolic processing.
- ABAP Scheme supports a subset of R7RS with some Racket extensions. Check the current list of features
- This documentation is the source of many of the 500+ tests implemented in the ABAP unit test suite.
- Access to ABAP global fields and function modules
- a programming environment to make it fun to use, featuring the editor and console views, a trace view, a graphical S-Expression viewer
S-expression for (* 2 (+ 3 4)) | workbench view |
---|---|
- R7RS alignment makes it easier to run open source Scheme code. This is however limited, as first class continuations (call cc) and hygienic macros (define-syntax) are missing
- Report ZZ_LISP_IDE - Main report for the workbench
- Include YY_LIB_LISP - Complete ABAP LISP library
- Include YY_LISP_AUNIT - a large ABAP Unit regression test suite
- Include YY_LISP_IDE - Editor/Tools
Class lcl_lisp_interpreter
evaluates your Scheme code in a string code
, using either method eval_repl( code )
which throws an exception on errors, or method eval_source( code )
catches exception:
DATA(response) = NEW lcl_lisp_interpreter( io_port = port
ii_log = log )->eval_source( code ).
port
is a buffered port that can allow input or output. log
implements a simple logging interface with 2 methods, put( ) and get( ).
For a dynamic IF statement
( PLAAB = '02' ) and ( DELKZ = 'BB') and ( LIFNR > '' ) and ( PLUMI = '-')
we concatenate the following Scheme expression in a string variable code
and evaluate.
(let
; Define local fields
((PLAAB (ab-data "GS_MDPS-PLAAB" ))
(DELKZ (ab-data "GS_MDPS-DELKZ" ))
(LIFNR (ab-data "GS_MDPS-LIFNR" ))
(PLUMI (ab-data "GS_MDPS-PLUMI" )))
(and (= PLAAB '02') (= DELKZ 'BB') (> LIFNR '') (= PLUMI '-')) )
The result on the expression either #t
or #f
.
(let (( profiles
(let ( (f3 (ab-function "BAPI_USER_GET_DETAIL")) )
( begin (ab-set f3 "USERNAME" (ab-get ab-sy "UNAME") ) ; param USERNAME = sy-uname
(f3) ; function module call
(ab-get f3 "PROFILES") ) ) ; return table PROFILES
) )
(let ((profile (ab-get profiles 1)) ) ; read table PROFILES index 1 INTO profile
(ab-get profile "BAPIPROF" ) ) ) ; read field profile-bapiprof
INTERFACE lif_input_port.
METHODS read IMPORTING iv_title TYPE string OPTIONAL
RETURNING VALUE(rv_input) TYPE string.
METHODS peek_char RETURNING VALUE(rv_char) TYPE char01.
METHODS is_char_ready RETURNING VALUE(rv_flag) TYPE flag.
METHODS read_char RETURNING VALUE(rv_char) TYPE char01.
METHODS put IMPORTING iv_text TYPE string.
ENDINTERFACE.
INTERFACE lif_output_port.
METHODS write IMPORTING element TYPE REF TO lcl_lisp.
METHODS display IMPORTING element TYPE REF TO lcl_lisp
RAISING lcx_lisp_exception.
ENDINTERFACE.
Read the ABAP Scheme announcement blog