Git Product home page Git Product logo

abap_scheme's Introduction

ABAP Scheme

Language: ABAP License: MIT

  • 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

Getting Started

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.

Why Scheme?

LISP Inside

  • 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.

Features

  • 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
s-exp 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

Architecture

  • 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

ABAP Integration

Interpreter

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( ).

Access to ABAP Fields

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.

Function Module Call

    (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

Optional: Console Interface

      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.

Workbench

abap_scheme abap_trace abap_expression

Read the ABAP Scheme announcement blog

abap_scheme's People

Contributors

larshp avatar nomssi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

abap_scheme's Issues

Implement apply

from R6RS
(apply proc arg1 . . . rest-args)

Rest-args must be a list. Proc should accept n arguments, where n is number of args plus the length of rest-args. The apply procedure calls proc with the elements of the list
(append (list arg1 . . . ) rest-args )
as the actual arguments.

Parameter Objects

(parameterize
((current-output-port
(open-output-string)))
(display "piece")
(display " by piece ")
(display "by piece.")
(newline)
(get-output-string (current-output-port)))
=โ‡’ "piece by piece by piece.\n"

quasiquoting

TO DO:

  • quasiquote ` (currently works as quote ')
  • unquote ,
  • unquote-splicing ,@

Input / Output

ports, input, output
Create classes implementing different input/output port:

  • from file
  • from CL_DEMO_OUTPUT

Enable selection/switch between console implementations - to be extended to accept opt. parameter

(display obj)
(display obj port)

(write obj)
(write obj port)

(newline)
(newline port)

(input-port? obj)
(output-port? obj)
(textal-port? obj)
(binary-port? obj)
(port? obj)

(input-port-open? obj)
(output-port-open? obj)

(current-input-port)
(current-output-port)
(current-error-port)

(close-port port)
(close-input-port port)
(close-output-port port)

(open-input-string string)
(open-output-string)
(get-output-string port)

;; deferred to new issue
(parameterize
((current-output-port
(open-output-string)))
(display "piece")
(display " by piece ")
(display "by piece.")
(newline)
(get-output-string (current-output-port)))
=โ‡’ "piece by piece by piece.\n"

(read)
(read port)

(read-char)
(read-char port)

(peek-char)
(peek-char port)

(char-ready?)
(char-rea

Implement named let

(let ''name'' (''bindings'') ''body'')

e.g.

  (let sum ((lst (list 1 2 3))
            (s 0))
    (if (null? lst)
        s
        (sum (cdr lst) (+ s (car lst)))))

Limit execution time of Evaluation

The developer should be able to define a maximal execution time for any ABAP Scheme Evaluation. If the time needed is larger, a TIME_OUT should occurs within the Workbench without ABAP Short Dump

ABAP Unit can also Limit the execution time of an ABAP Unit test. This is the functionality to replicate

Class CL_AUNIT_CLASSTEST_SESSIONFE
Method __CANCEL_RFC

implement do special form

Iterations are already possible with named let,
TO DO: do special form

    (do (( <variable1> <init1> <step1>) 
    . . . )
    (<testi> <expressioni> . . . )
    <commandi> . . . )

Scheme Identifier

||
|HelloWorld| are valid identifier that are not recognized by the parser yet

Internal declarations

in R7RS, a body is made of 0 or more declarations followed by expressions, so

  • internal defines must be placed before any expression
  • multiple define for the same variable are not allowed.

So the following programs should be wrong:

  (define (foo)
    (display 1)       ; not allowed before define
    (define bar 1)
    bar)

  (define (foo)
    (define bar 1)
    (define bar 2)   ; redefinition not allowe
    bar)

Top-level definitions do not have this restriction.

Missing TCO

Tail Cail Optimization is not supported yet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.