Skip to content

Commit

Permalink
Add GAP console session mode
Browse files Browse the repository at this point in the history
This is also appropriate for GAP .tst files
  • Loading branch information
fingolfin committed Aug 18, 2022
1 parent bb780f4 commit d3637be
Show file tree
Hide file tree
Showing 6 changed files with 1,706 additions and 3 deletions.
1 change: 1 addition & 0 deletions pygments/lexers/_mapping.py
Expand Up @@ -168,6 +168,7 @@
'FoxProLexer': ('pygments.lexers.foxpro', 'FoxPro', ('foxpro', 'vfp', 'clipper', 'xbase'), ('*.PRG', '*.prg'), ()),
'FreeFemLexer': ('pygments.lexers.freefem', 'Freefem', ('freefem',), ('*.edp',), ('text/x-freefem',)),
'FutharkLexer': ('pygments.lexers.futhark', 'Futhark', ('futhark',), ('*.fut',), ('text/x-futhark',)),
'GAPConsoleLexer': ('pygments.lexers.algebra', 'GAP session', ('gap-repl',), ('*.tst',), ()),
'GAPLexer': ('pygments.lexers.algebra', 'GAP', ('gap',), ('*.g', '*.gd', '*.gi', '*.gap'), ()),
'GDScriptLexer': ('pygments.lexers.gdscript', 'GDScript', ('gdscript', 'gd'), ('*.gd',), ('text/x-gdscript', 'application/x-gdscript')),
'GLShaderLexer': ('pygments.lexers.graphics', 'GLSL', ('glsl',), ('*.vert', '*.frag', '*.geo'), ('text/x-glslsrc',)),
Expand Down
58 changes: 55 additions & 3 deletions pygments/lexers/algebra.py
Expand Up @@ -10,11 +10,11 @@

import re

from pygments.lexer import RegexLexer, bygroups, words
from pygments.lexer import Lexer, RegexLexer, bygroups, do_insertions, words
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
Number, Punctuation, Whitespace
Number, Punctuation, Generic, Whitespace

__all__ = ['GAPLexer', 'MathematicaLexer', 'MuPADLexer', 'BCLexer']
__all__ = ['GAPLexer', 'GAPConsoleLexer', 'MathematicaLexer', 'MuPADLexer', 'BCLexer']


class GAPLexer(RegexLexer):
Expand Down Expand Up @@ -88,6 +88,58 @@ def analyse_text(text):
return min(score, 1.0)


class GAPConsoleLexer(Lexer):
"""
For GAP console sessions. Modeled after JuliaConsoleLexer.
.. versionadded:: 2.14
"""
name = 'GAP session'
aliases = ['gap-repl']
filenames = ['*.tst']

def get_tokens_unprocessed(self, text):
gaplexer = GAPLexer(**self.options)
start = 0
curcode = ''
insertions = []
output = False
error = False

for line in text.splitlines(True):
if line.startswith('gap> ') or line.startswith('brk> '):
insertions.append((len(curcode), [(0, Generic.Prompt, line[:5])]))
curcode += line[5:]
output = False
error = False
elif not output and line.startswith('> '):
insertions.append((len(curcode), [(0, Generic.Prompt, line[:2])]))
curcode += line[2:]
else:
if curcode:
yield from do_insertions(
insertions, gaplexer.get_tokens_unprocessed(curcode))
curcode = ''
insertions = []
if line.startswith('Error, ') or error:
yield start, Generic.Error, line
error = True
else:
yield start, Generic.Output, line
output = True
start += len(line)

if curcode:
yield from do_insertions(
insertions, gaplexer.get_tokens_unprocessed(curcode))

def analyse_text(text):
if re.search(r"(^gap> )", text):
return 0.9
else:
return 0.0


class MathematicaLexer(RegexLexer):
"""
Lexer for Mathematica source code.
Expand Down
60 changes: 60 additions & 0 deletions tests/examplefiles/gap-repl/euclidean.tst
@@ -0,0 +1,60 @@
#@local checkEuclideanRing
gap> START_TEST("euclidean.tst");

# test consistency of EuclideanDegree, EuclideanQuotient, EuclideanRemainder,
# and QuotientRemainder for some ring and elements of it
gap> checkEuclideanRing :=
> function(R, colls...)
> local coll1, coll2, a, b, deg_b, deg_r, q, r, qr;
> if Length(colls) >= 1 then coll1:=colls[1];
> elif Size(R) <= 100 then coll1 := R;
> else coll1 := List([1..100],i->Random(R));
> fi;
> if Length(colls) >= 2 then coll2:=colls[2];
> elif Size(R) <= 100 then coll2 := R;
> else coll2 := List([1..100],i->Random(R));
> fi;
> for b in coll1 do
> if IsZero(b) then continue; fi;
> deg_b := EuclideanDegree(R, b);
> for a in coll2 do
> q := EuclideanQuotient(R, a, b); Assert(0, q in R);
> r := EuclideanRemainder(R, a, b); Assert(0, r in R);
> if a <> q*b + r then Error("a <> q*b + r for ", [R,a,b]); fi;
> deg_r := EuclideanDegree(R, r);
> if not IsZero(r) and deg_r >= deg_b then Error("Euclidean degree did not decrease for ",[R,a,b]); fi;
> qr := QuotientRemainder(R, a, b);
> if qr <> [q, r] then Error("QuotientRemainder inconsistent for ", [R,a,b]); fi;
> od;
> od;
> return true;
> end;;

# rings in characteristic 0
gap> checkEuclideanRing(Integers,[-100..100],[-100..100]);
true
gap> checkEuclideanRing(Rationals);
true
gap> checkEuclideanRing(GaussianIntegers);
true
gap> checkEuclideanRing(GaussianRationals);
true

# finite fields
gap> ForAll(Filtered([2..50], IsPrimePowerInt), q->checkEuclideanRing(GF(q)));
true

# ZmodnZ
gap> ForAll([1..50], m -> checkEuclideanRing(Integers mod m));
true
gap> checkEuclideanRing(Integers mod ((2*3*5)^2));
true
gap> checkEuclideanRing(Integers mod ((2*3*5)^3));
true
gap> checkEuclideanRing(Integers mod ((2*3*5*7)^2));
true
gap> checkEuclideanRing(Integers mod ((2*3*5*7)^3));
true

#
gap> STOP_TEST( "euclidean.tst", 1);

0 comments on commit d3637be

Please sign in to comment.