1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-07 02:16:09 +02:00

userdiff: add support for Scheme

Add a diff driver for Scheme-like languages which recognizes top level
and local `define` forms, whether it is a function definition, binding,
syntax definition or a user-defined `define-xyzzy` form.

Also supports R6RS `library` forms, `module` forms along with class and
struct declarations used in Racket (PLT Scheme).

Alternate "def" syntax such as those in Gerbil Scheme are also
supported, like defstruct, defsyntax and so on.

The rationale for picking `define` forms for the hunk headers is because
it is usually the only significant form for defining the structure of
the program, and it is a common pattern for schemers to have local
function definitions to hide their visibility, so it is not only the top
level `define`'s that are of interest. Schemers also extend the language
with macros to provide their own define forms (for example, something
like a `define-test-suite`) which is also captured in the hunk header.

Since it is common practice to extend syntax with variants of a form
like `module+`, `class*` etc, those have been supported as well.

The word regex is a best-effort attempt to conform to R7RS[1] valid
identifiers, symbols and numbers.

[1] https://small.r7rs.org/attachment/r7rs.pdf (section 2.1)

Signed-off-by: Atharva Raykar <raykar.ath@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Atharva Raykar 2021-04-08 14:44:43 +05:30 committed by Junio C Hamano
parent 84d06cdc06
commit a437390310
18 changed files with 101 additions and 0 deletions

View File

@ -845,6 +845,8 @@ patterns are available:
- `rust` suitable for source code in the Rust language.
- `scheme` suitable for source code in the Scheme language.
- `tex` suitable for source code for LaTeX documents.

View File

@ -48,6 +48,7 @@ diffpatterns="
python
ruby
rust
scheme
tex
custom1
custom2

7
t/t4018/scheme-class Normal file
View File

@ -0,0 +1,7 @@
(define book-class%
(class* () object% RIGHT
(field (pages 5))
(field (ChangeMe 5))
(define/public (letters)
(* pages 500))
(super-new)))

4
t/t4018/scheme-def Normal file
View File

@ -0,0 +1,4 @@
(def (some-func x y z) RIGHT
(let ((a x)
(b y))
(ChangeMe a b)))

View File

@ -0,0 +1,4 @@
(defmethod {print point} RIGHT
(lambda (self)
(with ((point x y) self)
(printf "{ChangeMe x:~a y:~a}~n" x y))))

View File

@ -0,0 +1,7 @@
(define bar-class%
(class object%
(field (info 5))
(define/public (foo) RIGHT
(+ info 42)
(* info ChangeMe))
(super-new)))

View File

@ -0,0 +1,8 @@
(define-syntax define-test-suite RIGHT
(syntax-rules ()
((_ suite-name (name test) ChangeMe ...)
(define suite-name
(let ((tests
`((name . ,test) ...)))
(lambda ()
(run-suite 'suite-name tests)))))))

View File

@ -0,0 +1,4 @@
(define* (some-func x y z) RIGHT
(let ((a x)
(b y))
(ChangeMe a b)))

11
t/t4018/scheme-library Normal file
View File

@ -0,0 +1,11 @@
(library (my-helpers id-stuff) RIGHT
(export find-dup)
(import (ChangeMe))
(define (find-dup l)
(and (pair? l)
(let loop ((rest (cdr l)))
(cond
[(null? rest) (find-dup (cdr l))]
[(bound-identifier=? (car l) (car rest))
(car rest)]
[else (loop (cdr rest))])))))

View File

@ -0,0 +1,4 @@
(define (higher-order)
(define local-function RIGHT
(lambda (x)
(car "this is" "ChangeMe"))))

6
t/t4018/scheme-module Normal file
View File

@ -0,0 +1,6 @@
(module A RIGHT
(export with-display-exception)
(extern (display-exception display-exception ChangeMe))
(def (with-display-exception thunk)
(with-catch (lambda (e) (display-exception e (current-error-port)) e)
thunk)))

View File

@ -0,0 +1,4 @@
(define (some-func x y z) RIGHT
(let ((a x)
(b y))
(ChangeMe a b)))

View File

@ -0,0 +1,6 @@
(define-test-suite record\ case-tests RIGHT
(record-case-1 (lambda (fail)
(let ((a (make-foo 1 2)))
(record-case a
((bar x) (ChangeMe))
((foo a b) (+ a b)))))))

View File

@ -325,6 +325,7 @@ test_language_driver perl
test_language_driver php
test_language_driver python
test_language_driver ruby
test_language_driver scheme
test_language_driver tex
test_expect_success 'word-diff with diff.sbe' '

11
t/t4034/scheme/expect Normal file
View File

@ -0,0 +1,11 @@
<BOLD>diff --git a/pre b/post<RESET>
<BOLD>index 74b6605..63b6ac4 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,6 +1,6 @@<RESET>
(define (<RED>myfunc a b<RESET><GREEN>my-func first second<RESET>)
; This is a <RED>really<RESET><GREEN>(moderately)<RESET> cool function.
(<RED>this\place<RESET><GREEN>that\place<RESET> (+ 3 4))
(define <RED>some-text<RESET><GREEN>|a greeting|<RESET> "hello")
(let ((c (<RED>+ a b<RESET><GREEN>add1 first<RESET>)))
(format "one more than the total is %d" (<RED>add1<RESET><GREEN>+<RESET> c <GREEN>second<RESET>))))

6
t/t4034/scheme/post Normal file
View File

@ -0,0 +1,6 @@
(define (my-func first second)
; This is a (moderately) cool function.
(that\place (+ 3 4))
(define |a greeting| "hello")
(let ((c (add1 first)))
(format "one more than the total is %d" (+ c second))))

6
t/t4034/scheme/pre Normal file
View File

@ -0,0 +1,6 @@
(define (myfunc a b)
; This is a really cool function.
(this\place (+ 3 4))
(define some-text "hello")
(let ((c (+ a b)))
(format "one more than the total is %d" (add1 c))))

View File

@ -191,6 +191,15 @@ PATTERNS("rust",
"[a-zA-Z_][a-zA-Z0-9_]*"
"|[0-9][0-9_a-fA-Fiosuxz]*(\\.([0-9]*[eE][+-]?)?[0-9_fF]*)?"
"|[-+*\\/<>%&^|=!:]=|<<=?|>>=?|&&|\\|\\||->|=>|\\.{2}=|\\.{3}|::"),
PATTERNS("scheme",
"^[\t ]*(\\(((define|def(struct|syntax|class|method|rules|record|proto|alias)?)[-*/ \t]|(library|module|struct|class)[*+ \t]).*)$",
/*
* R7RS valid identifiers include any sequence enclosed
* within vertical lines having no backslashes
*/
"\\|([^\\\\]*)\\|"
/* All other words should be delimited by spaces or parentheses */
"|([^][)(}{[ \t])+"),
PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
"[={}\"]|[^={}\" \t]+"),
PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",