Hi Quian,
thanks for your reply, here is the output. Meanwhile I found the reason
for the error, which I could eliminate, as this feature is not required
for the computations right now. But may be crucial for other application.
I enhanced Character and String with greek letters and other useful
functions. Code string-enhanced.spad is included. Also symbol-jg.spad
with signatures like alpha: () -> Sybol
There I had to do a boot strapping process (forgot why) for signatur
greek?: () -> Boolean, which one had to compile first without code and
then with code. But exactly this process causes the error now.
Please compile symbol-jg and string-enhanced (2 times, first with code
of greek? commented out and then with its code). Then calling e.g.
alpha() reproduces the error.
I am curious to learn what is going wrong now. And, if this can be fixed
I would appreciate to include my enhancements to the distribution.
Thanks and regards
Johannes
(4) -> fnvwh : FileName :=
filename("/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS",
"VWH_2024_newspad", "csv")
>> System error:
invalid number of arguments: 2
(4) ->
(4) ->
(4) -> )set break break
(4) -> fnvwh : FileName :=
filename("/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS",
"VWH_2024_newspad", "csv")
debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR in thread
#<THREAD "main thread" RUNNING {7006C65233}>:
invalid number of arguments: 2
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [REPLACE-FUNCTION] Call a different function with the same arguments
1: [CALL-FORM ] Call a different form
2: [ABORT ] Exit from the current thread.
(|make_full_CVEC| 1 34) [external]
source: (DEFUN |make_full_CVEC| (SINT) (|make_full_CVEC2| SINT #\ ))
0]
:backtrace
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {7006C65233}>
0: (|make_full_CVEC| 1 34) [external]
1: (|LNAGG-;concat;ASA;3|
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv"
34 #1=#((|LinearAggregate&| #2=(|String|) (|Character|)) (#3=#<FUNCTION
|lookupComplete|> #1# #(|trim| 197 |sorted?| 203 |sort!| 208 |sort| 213
|rightTrim| 224 |reverse| 230 ...)) NIL 31 (#(T) #((|Join| (|mkCategory|
# # NIL NIL))) . #(1 6 8 0 9 1 6 8 0 10 2 6 ...)) NIL #4=#(#2#
(#<FUNCTION |lookupIncomplete|> #4# #(|uentries| 103 |ucodeToString| 108
|toInteger| 113 |toDecimalExpansion| 118 |string| 123 |qsetelt!| 128
...)) NIL 16382 (#(T |StringAggregate&| #(# # NIL 0 # NIL #4# #5=# # # #
# ...) T #1# |IndexedAggregate&| |Collection&| |OrderedSet&|
|HomogeneousAggregate&| T |SetCategory&| |Aggregate&| ...)
#((|StringCategory|) (|StringAggregate|) (|OneDimensionalArrayAggregate|
9) (|FiniteLinearAggregate| 9) (|LinearAggregate| 9) (|IndexedAggregate|
11 9) (|Collection| 9) (|OrderedSet|) (|HomogeneousAggregate| 9)
(|Comparable|) (|SetCategory|) (|Aggregate|) ...) . #(1 0 6 0 7 2 9 8 0
0 10 1 ...)) #6=#((|IndexedString| 1) (#3# #6# #(~= 97 |upperCase!| 103
|upperCase| 108 |trim| 113 |swap!| 125 |suffix?| 132 ...)) NIL 4194175
(#(|StringAggregate&| |OneDimensionalArrayAggregate&| T
|LinearAggregate&| |IndexedAggregate&| |Collection&| |OrderedSet&|
|HomogeneousAggregate&| T |Aggregate&| |EltableAggregate&| NIL ...) #(#
# # # # # # # # # # # ...) . #(2 19 0 18 18 20 1 19 0 18 22 1 ...)) NIL
1 (|NonNegativeInteger|) (|Character|) (#<FUNCTION
|ISTRING;new;NniC$;1|> . #6#) (#<FUNCTION |ISTRING;empty;$;2|> . #6#)
(|Boolean|) ...) (|List| 9) (#7=#<FUNCTION |newGoGet|> #4# 0 . |parts|)
(|Boolean|) #5# (#7# #4# 5 . ~=) (|Integer|) ...) #5# (|Integer|) (#7#
#1# 0 . |minIndex|) (#7# #1# 5 . |maxIndex|) (|List| 8) ...))
2: (|OUTFORM;outputForm;S$;13|
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv"
#1=#((|OutputForm|) (#<FUNCTION |lookupComplete|> #1# #(~= 153 |zag| 165
|vspace| 171 |vconcat| 176 |tensor| 187 |supersub| 193 ...)) NIL 0
(#(|SetCategory&| |BasicType&| T T) #((|SetCategory|) (|BasicType|)
(|ConvertibleTo| 43) (|CoercibleTo| 21)) . #(2 6 0 2 0 7 1 12 11 0 13 1
...)) NIL (|List| $$) (#<FUNCTION |newGoGet|> #1# 0 . |cons|)
#2=#((|SExpression|) (#<FUNCTION |lookupIncomplete|> #2# #()) NIL 0 (#(T
|SetCategory&| |BasicType&| T) #((|SExpressionCategory| 9 10 7 8)
(|SetCategory|) (|BasicType|) (|CoercibleTo| 14)) . #())
(|SExpressionOf| 9 10 7 8) (|List| 7) (|Integer|) (|DoubleFloat|)
(|String|) (|Symbol|) (|List| $) ...) (|Void|) (#<FUNCTION
|OUTFORM;print;$V;2|> . #1#) (|Boolean|) ...))
3: (|coerceByFunction| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
4: (|coerceIntTower| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
5: (|coerceInt1| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
6: (|coerceInt| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
7: (|coerceInt0| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
8: (|coerceInteractive| ((|FileName|) WRAPPED .
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv")
(|OutputForm|))
9: (|output|
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv"
(|FileName|))
10: (|recordAndPrint|
#P"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS/VWH_2024_newspad.csv"
(|FileName|))
11: (|processInteractive1| (LET (|:| |fnvwh| |FileName|) (|filename|
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS"
"VWH_2024_newspad" "csv")) (|Assign| (|listOf| (|Tagged| ((|id| #) .
|fnvwh|) ((|id| #) . |FileName|))) (|Application| ((|id| (|posn| # .
20)) . |filename|) (|Tuple| (|listOf| (# .
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS")
(# . "VWH_2024_newspad") (# . "csv"))))))
12: (|processInteractive| (LET (|:| |fnvwh| |FileName|) (|filename|
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS"
"VWH_2024_newspad" "csv")) (|Assign| (|listOf| (|Tagged| ((|id| #) .
|fnvwh|) ((|id| #) . |FileName|))) (|Application| ((|id| (|posn| # .
20)) . |filename|) (|Tuple| (|listOf| (# .
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS")
(# . "VWH_2024_newspad") (# . "csv"))))))
13: (|intInterpretPform| (|Assign| (|listOf| (|Tagged| ((|id| #) .
|fnvwh|) ((|id| #) . |FileName|))) (|Application| ((|id| (|posn| # .
20)) . |filename|) (|Tuple| (|listOf| (# .
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS")
(# . "VWH_2024_newspad") (# . "csv"))))))
14: (|phInterpret| ((|carrier| (|ok?| . T) (|ptreePremacro| .
#1=(|Assign| (|listOf| #) (|Application| # #))) (|ptree| . #1#) (|lines|
((# . 1) . "fnvwh : FileName :=
filename(\"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS\",
\"VWH_2024_newspad\", \"csv\")")) (|messages|) (|stepNumber| . 1))))
15: (|ncConversationPhase| #<FUNCTION |phInterpret|> (((|carrier| (|ok?|
. T) (|ptreePremacro| . #1=(|Assign| # #)) (|ptree| . #1#) (|lines| (# .
"fnvwh : FileName :=
filename(\"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS\",
\"VWH_2024_newspad\", \"csv\")")) (|messages|) (|stepNumber| . 1)))))
16: (|intloopSpadProcess,interp| ((|carrier| (|ok?| . T)
(|ptreePremacro| . #1=(|Assign| (|listOf| #) (|Application| # #)))
(|ptree| . #1#) (|lines| ((# . 1) . "fnvwh : FileName :=
filename(\"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS\",
\"VWH_2024_newspad\", \"csv\")")) (|messages|) (|stepNumber| . 1)))
(|Assign| (|listOf| (|Tagged| ((|id| #) . |fnvwh|) ((|id| #) .
|FileName|))) (|Application| ((|id| (|posn| # . 20)) . |filename|)
(|Tuple| (|listOf| (# .
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS")
(# . "VWH_2024_newspad") (# . "csv"))))) T)
17: (|intloopSpadProcess| 1 ((((0 #1="fnvwh : FileName :=
filename(\"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS\",
\"VWH_2024_newspad\", \"csv\")" 1 1 "strings") . 1) . #1#)) (|Assign|
(|listOf| (|Tagged| ((|id| #) . |fnvwh|) ((|id| #) . |FileName|)))
(|Application| ((|id| (|posn| # . 20)) . |filename|) (|Tuple| (|listOf|
(# .
"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS")
(# . "VWH_2024_newspad") (# . "csv"))))) T)
18: (|intloopProcess| 1 T (((((# . 1) . "fnvwh : FileName :=
filename(\"/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS\",
\"VWH_2024_newspad\", \"csv\")")) (|Assign| (|listOf| (|Tagged| # #))
(|Application| (# . |filename|) (|Tuple| #)))) |nonnullstream|
#1=#<FUNCTION |next1|> #<FUNCTION |ncloopParse|> (|nonnullstream| #1#
#<FUNCTION |fakepile|> (|nullstream|))))
19: (|intloopReadConsole| #<unavailable argument> #<unavailable argument>)
20: (|SpadInterpretStream| 1 NIL T)
21: (|int_loop|)
22: (|ncTopLevel|)
23: (|runspad|)
24: (|spad|)
25: (FRICAS-RESTART)
26: ((LAMBDA NIL :IN FRICAS-LISP::SAVE-CORE-RESTART))
27: ((FLET SB-UNIX::BODY :IN SB-IMPL::START-LISP))
28: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-IMPL::START-LISP))
29: (SB-IMPL::START-LISP)
0]
Am 25.11.23 um 01:45 schrieb Qian Yun:
Hi,
I can't reproduce this problem either.
Did you compile FriCAS or use a binary?
Can you show me the backtrace by:
)set break break
filename(...)
Then type ":backtrace" in the debugger.
- Qian
On 11/25/23 03:59, Prof. Dr. Johannes Grabmeier wrote:
Hi all,
get the following error:
(7) ->
filename("/Users/jgrabmeier/stadtrat-deggendorf/haushalt/hh-plan-2024/entwurfHaushaltFriCAS",
"xxx", "input")
>> System error:
invalid number of arguments: 2
filename calls fnameMake from LISP
filename(d, n, e) == fnameMake(d, n, e)$Lisp
what is wrong? I have FriCAS 1.3.8 on SBCL 2.1.2 on Apple M2 Pro
Would be thankful for urgent reply, as I have to use the results of
the computations in a short time frame.
--
Mit freundlichen Grüßen
Johannes Grabmeier
Prof. Dr. Johannes Grabmeier,
Köckstraße 1, D-94469 Deggendorf
Tel. +49-(0)-991-2979584, Tel. +49-(0)-151-681-70756
Fax: +49-(0)-991-2979592
--
Mit freundlichen Grüßen
Johannes Grabmeier
Prof. Dr. Johannes Grabmeier,
Köckstraße 1, D-94469 Deggendorf
Tel. +49-(0)-991-2979584, Tel. +49-(0)-151-681-70756
Fax: +49-(0)-991-2979592
--
You received this message because you are subscribed to the Google Groups "FriCAS -
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/c0ce47ea-33e5-418a-8714-2ae323c4cc66%40grabmeier.net.
)abbrev domain SYMBOL Symbol
++ Author: Stephen Watt
++ Date Created: 1986
++ Date Last Updated: 29.08.2019 J. Grabmeier partial
++ Date Last Updated: 17.09.2018 J. Grabmeier Greek
++ Description:
++ Basic and scripted symbols. Extended for easily created Greek letters as
symbols.
++ Keywords: symbol.
Symbol() : Exports == Implementation where
L ==> List OutputForm
Scripts ==> Record(sub : L, sup : L, presup : L, presub : L, args : L)
Exports ==> Join(OrderedSet, ConvertibleTo InputForm, OpenMath,
ConvertibleTo Symbol,
ConvertibleTo Pattern Integer, ConvertibleTo Pattern Float,
PatternMatchable Integer, PatternMatchable Float) with
new : () -> %
++ new() returns a new symbol whose name starts with %.
new : % -> %
++ new(s) returns a new symbol whose name starts with %s.
resetNew : () -> Void
++ resetNew() resets the internals counters that new() and
++ new(s) use to return distinct symbols every time.
-- begin new code jg
newGreek : () -> %
++ newGreek() returns the next greek character.
resetNewGreek : () -> Void
++ resetNewGreek() resets the internals counters that newGreek()
++ use to return distinct symbols every time.
-- end new code jg
coerce : String -> %
++ coerce(s) converts the string s to a symbol.
name : % -> %
++ name(s) returns s without its scripts.
scripted? : % -> Boolean
++ scripted?(s) is true if s has been given any scripts.
scripts : % -> Scripts
++ scripts(s) returns all the scripts of s.
script : (%, List L) -> %
++ script(s, [a, b, c, d, e]) returns s with subscripts a,
++ superscripts b, pre-superscripts c, pre-subscripts d,
++ and argument-scripts e. Omitted components are taken to be empty.
++ For example, \spad{script(s, [a, b, c])} is equivalent to
++ \spad{script(s, [a, b, c, [], []])}.
script : (%, Scripts) -> %
++ script(s, [a, b, c, d, e]) returns s with subscripts a,
++ superscripts b, pre-superscripts c, pre-subscripts d,
++ and argument-scripts e.
subscript : (%, L) -> %
++ subscript(s, [a1, ..., an]) returns s
++ subscripted by \spad{[a1, ..., an]}.
superscript : (%, L) -> %
++ superscript(s, [a1, ..., an]) returns s
++ superscripted by \spad{[a1, ..., an]}.
argscript : (%, L) -> %
++ argscript(s, [a1, ..., an]) returns s
++ arg-scripted by \spad{[a1, ..., an]}.
elt : (%, L) -> %
++ elt(s, [a1, ..., an]) or s([a1, ..., an]) returns s subscripted by
\spad{[a1, ..., an]}.
string : % -> String
++ string(s) converts the symbol s to a string.
++ Error: if the symbol is subscripted.
sample : constant -> %
++ sample() returns a sample of %
-- begin new code jg
partial: constant -> %
++ partial() returns ∂.
tabulator: constant -> %
++ tabulator() returns .
endOfLine: constant -> %
++ endOfLine() returns the end-of-line chacter.
alpha: constant -> %
++ alpha() returns α.
beta: constant -> %
++ beta() returns β.
gamma: constant -> %
++ gamm() returns γ.
delta: constant -> %
++ delta() returns δ.
epsilon: constant -> %
++ epsilon() returns ε.
zeta: constant -> %
++ zeta() returns ς.
eta: constant -> %
++ eta() returns η.
theta: constant -> %
++ theta() returns θ.
iota: constant -> %
++ iota() returns ι.
kappa: constant -> %
++ kappa() returns κ.
lambda: constant -> %
++ lambda() returns λ.
mu: constant -> %
++ mu() returns μ.
nu: constant -> %
++ nu() returns ν.
xi: constant -> %
++ xi() returns ξ.
omicron: constant -> %
++ omicron() returns ο.
pi: constant -> %
++ pi() returns π.
rho: constant -> %
++ rho() returns ρ.
sigma: constant -> %
++ sigma() returns σ.
tau: constant -> %
++ tau() returns τ.
upsilon: constant -> %
++ upsilon() returns υ.
phi: constant -> %
++ phi() returns φ.
chi: constant -> %
++ chi() returns χ.
psi: constant -> %
++ psi() returns ψ.
omega: constant -> %
++ omega() returns ω.
Alpha: constant -> %
++ Alpha() returns Α.
Beta: constant -> %
++ Beta() returns Β.
Gamma: constant -> %
++ Gamm() returns Γ.
Delta: constant -> %
++ Delta() returns Δ.
Epsilon: constant -> %
++ Epsilon() returns Ε.
Zeta: constant -> %
++ Zeta() returns Ζ.
Eta: constant -> %
++ Eta() returns Η.
Theta: constant -> %
++ Theta() returns Θ.
Iota: constant -> %
++ Iota() returns Ι.
Kappa: constant -> %
++ Kappa() returns Κ.
Lambda: constant -> %
++ Lambda() returns Λ.
Mu: constant -> %
++ Mu() returns Μ.
Nu: constant -> %
++ Nu() returns Ν.
Xi: constant -> %
++ Xi() returns Ξ.
Omicron: constant -> %
++ Omicron() returns Ο.
Pi: constant -> %
++ Pi() returns Π.
Rho: constant -> %
++ Rho() returns Ρ.
Sigma: constant -> %
++ Sigma() returns Σ.
Tau: constant -> %
++ Tau() returns Τ.
Upsilon: constant -> %
++ Upsilon() returns Υ.
Phi: constant -> %
++ Phi() returns Φ.
Chi: constant -> %
++ Chi() returns Χ.
Psi: constant -> %
++ Psi() returns Ψ.
Omega: constant -> %
++ omega() returns Ω.
-- ["Α", "Β", "Γ", "Δ", "Ε", "Ζ", "Η", "Θ", "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ",
"Ο", "Π", "Ρ", "", "Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"
-- end new code jg
Implementation ==> add
import from Character
import from List(OutputForm)
import from List(%)
count : Reference(Integer) := ref 0
xcount : AssociationList(%, Integer) := empty()
istrings : PrimitiveArray(String) :=
construct ["0","1","2","3","4","5","6","7","8","9"]
-- the following 3 strings shall be of empty intersection
nums:String := "0123456789"
ALPHAS:String := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alphas:String := "abcdefghijklmnopqrstuvwxyz"
-- begin new code jg
greekCount : Reference(Integer) := ref 0
greekLetters : String := concat [index(i :: PositiveInteger)$Character
:: String for i in 946..970]
-- end new code jg
writeOMSym(dev : OpenMathDevice, x : %) : Void ==
scripted? x =>
error "Cannot convert a scripted symbol to OpenMath"
OMputVariable(dev, x pretend Symbol)
OMwrite(dev : OpenMathDevice, x : %, wholeObj : Boolean) : Void ==
if wholeObj then
OMputObject(dev)
writeOMSym(dev, x)
if wholeObj then
OMputEndObject(dev)
hd:String := "*"
lhd := #hd
ord0 := ord char("0")$Character
pcnt ==> 4
istring : Integer -> String
syprefix : Scripts -> String
syscripts : Scripts -> L
convert(s : %) : InputForm ==
n: InputForm := (name s) pretend InputForm
not scripted? s => n
ls := scripts s
A: List InputForm := [convert(e)@InputForm for e in ls.sub]
B: List InputForm := [convert(e)@InputForm for e in ls.sup]
C: List InputForm := [convert(e)@InputForm for e in ls.presup]
D: List InputForm := [convert(e)@InputForm for e in ls.presub]
E: List InputForm := [convert(e)@InputForm for e in ls.args]
a: InputForm := convert('script)$InputForm
b: InputForm := convert('construct)$InputForm
FF: List List InputForm := [cons(b, e) for e in [A, B, C, D, E]]
G: List InputForm := [convert(F)$InputForm for F in FF]
d: InputForm := convert(cons(b, G))$InputForm
convert([a, n, d])$InputForm
convert(s : %) : Symbol == s pretend Symbol
coerce(s : String) : % == VALUES(INTERN(s)$Lisp)$Lisp
x = y == EQUAL(x, y)$Lisp
hashUpdate!(hs, s) == update!(hs, SXHASH(s)$Lisp)$HashState
x < y == GGREATERP(y, x)$Lisp
coerce(x : %) : OutputForm ==
not(scripted? x) => outputForm(x pretend Symbol)
ss : Scripts := scripts x
rsl : List(L) := [ss.presub, ss.presup, ss.sup, ss.sub]
sl : L := []
for si in rsl repeat
empty?(sl) and empty?(si) => "iterate"
se :=
#si = 1 => first(si)
commaSeparate(si)
sl := cons(se, sl)
x0 := scripts(outputForm(name(x) pretend Symbol), sl)
a := ss.args
empty?(a) => x0
prefix(x0, a)
subscript(sy, lx) == script(sy, [lx, [], [], [], []])
elt(sy, lx) == subscript(sy, lx)
superscript(sy, lx) == script(sy, [[], lx, [], [], []])
argscript(sy, lx) == script(sy, [[], [], [], [], lx])
patternMatch(x : %, p : Pattern Integer, l : PatternMatchResult(Integer,
%))==
(patternMatch(x pretend Symbol, p, l pretend
PatternMatchResult(Integer, Symbol))$PatternMatchSymbol(Integer))
pretend PatternMatchResult(Integer, %)
patternMatch(x : %, p : Pattern Float, l : PatternMatchResult(Float, %)) ==
(patternMatch(x pretend Symbol, p, l pretend
PatternMatchResult(Float, Symbol))$PatternMatchSymbol(Float))
pretend PatternMatchResult(Float, %)
convert(x : %) : Pattern(Float) ==
coerce(x pretend Symbol)$Pattern(Float)
convert(x : %) : Pattern(Integer) ==
coerce(x pretend Symbol)$Pattern(Integer)
syprefix sc ==
ns : List Integer := [#sc.sub, #sc.sup, #sc.presup, #sc.presub]
concat concat(concat(hd, istring(#sc.args)),
[istring n for n in ns])
syscripts sc ==
all := sc.presub
all := concat(sc.presup, all)
all := concat(sc.sup, all)
all := concat(sc.sub, all)
concat(all, sc.args)
script(sy : %, ls : List L) ==
sc : Scripts := [[], [], [], [], []]
if not(empty?(ls)) then (sc.sub := first(ls); ls := rest(ls))
if not(empty?(ls)) then (sc.sup := first(ls); ls := rest(ls))
if not(empty?(ls)) then (sc.presup := first(ls); ls := rest(ls))
if not(empty?(ls)) then (sc.presub := first(ls); ls := rest(ls))
if not(empty?(ls)) then (sc.args := first(ls); ls := rest(ls))
script(sy, sc)
script(sy : %, sc : Scripts) ==
scripted? sy => error "Cannot add scripts to a scripted symbol"
(concat(concat(syprefix sc, string name sy)::%::OutputForm,
syscripts sc)) pretend %
string e ==
not scripted? e => PNAME(e)$Lisp
error "Cannot form string from non-atomic symbols."
-- Scripts ==> Record(sub: L, sup: L, presup: L, presub: L, args: L)
latex e ==
s : String := (PNAME(name e)$Lisp) pretend String
if #s > 1 and s.1 ~= char "\" then
s := concat("\mbox{\it ", concat(s, "}")$String)$String
not scripted? e => s
ss : Scripts := scripts e
lo : List OutputForm := ss.sub
sc : String
if not empty? lo then
sc := "__{"
while not empty? lo repeat
sc := concat(sc, latex first lo)$String
lo := rest lo
if not empty? lo then sc := concat(sc, ", ")$String
sc := concat(sc, "}")$String
s := concat(s, sc)$String
lo := ss.sup
if not empty? lo then
sc := "^{"
while not empty? lo repeat
sc := concat(sc, latex first lo)$String
lo := rest lo
if not empty? lo then sc := concat(sc, ", ")$String
sc := concat(sc, "}")$String
s := concat(s, sc)$String
lo := ss.presup
if not empty? lo then
sc := "{}^{"
while not empty? lo repeat
sc := concat(sc, latex first lo)$String
lo := rest lo
if not empty? lo then sc := concat(sc, ", ")$String
sc := concat(sc, "}")$String
s := concat(sc, s)$String
lo := ss.presub
if not empty? lo then
sc := "{}__{"
while not empty? lo repeat
sc := concat(sc, latex first lo)$String
lo := rest lo
if not empty? lo then sc := concat(sc, ", ")$String
sc := concat(sc, "}")$String
s := concat(sc, s)$String
lo := ss.args
if not empty? lo then
sc := "\left( {"
while not empty? lo repeat
sc := concat(sc, latex first lo)$String
lo := rest lo
if not empty? lo then sc := concat(sc, ", ")$String
sc := concat(sc, "} \right)")$String
s := concat(s, sc)$String
s
anyRadix(n : Integer, s : String) : String ==
ns:String := ""
repeat
qr := divide(n, #s)
n := qr.quotient
ns := concat(s.(qr.remainder+minIndex s), ns)
if zero?(n) then return ns
new() ==
sym := anyRadix(count()::Integer, ALPHAS)
count() := count() + 1
concat("%",sym)::%
-- begin new code jg
newGreek() ==
sym := anyRadix(greekCount()::Integer, greekLetters)
greekCount() := greekCount() + 1
sym :: %
-- end new code jg
new x ==
n : Integer :=
(u := search(x, xcount)) case "failed" => 0
inc(u::Integer)
xcount(x) := n
xx :=
not scripted? x => string x
string name x
xx := concat("%",xx)
xx :=
(position(xx.maxIndex(xx), nums)>=minIndex(nums)) =>
concat(xx, anyRadix(n, alphas))
concat(xx, anyRadix(n, nums))
not scripted? x => xx::%
script(xx::%, scripts x)
resetNew() ==
count() := 0
for k in keys xcount repeat remove!(k, xcount)
void
-- begin new code jg
resetNewGreek() ==
greekCount() := 0
void
-- end new code jg
scripted? sy ==
not ATOM(sy)$Lisp
of_list(x : %) : L == x pretend L
name sy ==
not scripted? sy => sy
str := string(first(of_list(sy)) pretend %)
si := lhd + pcnt + 2
str(si..#str)::%
scripts sy ==
not scripted? sy => [[], [], [], [], []]
nscripts : List NonNegativeInteger := [0, 0, 0, 0, 0]
lscripts : List L := [[], [], [], [], []]
str := string(first(of_list(sy)) pretend %)
nstr := #str
m := minIndex nscripts
for i in m.. for j in (lhd + 1)..(lhd + pcnt + 1) repeat
nscripts.i := (ord(str.j) - ord0)::NonNegativeInteger
-- Put the number of function scripts at the end.
nscripts := concat(rest nscripts, first nscripts)
allscripts := rest(of_list(sy))
m := minIndex lscripts
for i in m.. for n in nscripts repeat
#allscripts < n => error "Improper script count in symbol"
lscripts.i := first(allscripts, n)
allscripts := rest(allscripts, n)
[lscripts.m, lscripts.(m+1), lscripts.(m+2),
lscripts.(m+3), lscripts.(m+4)]
istring n ==
n > 9 => error "Can have at most 9 scripts of each kind"
istrings.(n + minIndex istrings)
sample() == "aSymbol"::%
-- begin new code jg
getUTF(i : PositiveInteger): % ==
index(i :: PositiveInteger)$Character :: String :: %
partial(): % == getUTF(8707)
tabulator(): % == getUTF(9225)
endOfLine(): % == getUTF(10)
-- α, β, γ, δ, ε, ζ, η, θ, ι, κ, λ, μ, ν, ξ, ο, π, ρ, ς, σ, τ, υ, φ, χ, ψ, ω,
alpha(): % == getUTF(946)
beta(): % == getUTF(947)
gamma(): % == getUTF(948)
delta(): % == getUTF(949)
epsilon(): % == getUTF(950)
zeta(): % == getUTF(951)
eta(): % == getUTF(952)
theta(): % == getUTF(953)
iota(): % == getUTF(954)
kappa(): % == getUTF(955)
lambda(): % == getUTF(956)
mu(): % == getUTF(957)
nu(): % == getUTF(958)
xi(): % == getUTF(959)
omicron(): % == getUTF(960)
pi(): % == getUTF(961)
rho(): % == getUTF(962)
--?? (): % == getUTF(963)
sigma(): % == getUTF(964)
tau(): % == getUTF(965)
upsilon(): % == getUTF(966)
phi(): % == getUTF(967)
chi(): % == getUTF(968)
psi(): % == getUTF(969)
omega(): % == getUTF(670)
Alpha(): % == getUTF(914)
Beta(): % == getUTF(915)
Gamma(): % == getUTF(916)
Delta(): % == getUTF(917)
Epsilon(): % == getUTF(918)
Zeta(): % == getUTF(919)
Eta(): % == getUTF(920)
Theta(): % == getUTF(921)
Iota(): % == getUTF(922)
Kappa(): % == getUTF(923)
Lambda(): % == getUTF(924)
Mu(): % == getUTF(925)
Nu(): % == getUTF(926)
Xi(): % == getUTF(927)
Omicron(): % == getUTF(928)
Pi(): % == getUTF(929)
Rho(): % == getUTF(930)
--?? (): % == getUTF(931)
Sigma(): % == getUTF(932)
Tau(): % == getUTF(933)
Upsilon(): % == getUTF(934)
Phi(): % == getUTF(935)
Chi(): % == getUTF(936)
Psi(): % == getUTF(937)
Omega(): % == getUTF(938)
-- end new code jg
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
)abbrev domain CHAR Character
++ Author: Stephen M. Watt
++ Date Created: July 1986
++ Basic Operations: char
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: character, string
++ Examples:
++ References:
++ Description:
++ This domain provides the basic character data type.
++ ATTENTION: greek? code, not its definition
++ must be commented out for first compilation run, boot strapping!
--Character : OrderedFinite() with
Character : Export == Implementation where
OF ==> OutputForm
Export ==> OrderedFinite() with
ord : % -> Integer
++ ord(c) provides an integral code corresponding to the
++ character c. It is always true that \spad{char ord c = c}.
char : Integer -> %
++ char(i) provides a character corresponding to the integer
++ code i. It is always true that \spad{ord char i = i}.
char : String -> %
++ char(s) provides a character from a string s of length one.
space : () -> %
++ space() provides the blank character.
-- begin new code jg
infinityCharacter : () -> %
++ infinityCharacter() provides ∞.
-- end new code jg
quote : () -> %
++ quote() provides the string quote character, \spad{"}.
escape : () -> %
++ escape() provides the escape character, \spad{_}, which
++ is used to allow quotes and other characters {\em within}
++ strings.
newline : () -> %
++ newline() provides the newline character.
upperCase : % -> %
++ upperCase(c) converts a lower case letter to the corresponding
++ upper case letter. If c is not a lower case letter, then
++ it is returned unchanged.
lowerCase : % -> %
++ lowerCase(c) converts an upper case letter to the corresponding
++ lower case letter. If c is not an upper case letter, then
++ it is returned unchanged.
digit? : % -> Boolean
++ digit?(c) tests if c is a digit character,
++ i.e. one of 0..9.
hexDigit? : % -> Boolean
++ hexDigit?(c) tests if c is a hexadecimal numeral,
++ i.e. one of 0..9, a..f or A..F.
alphabetic? : % -> Boolean
++ alphabetic?(c) tests if c is a letter,
++ i.e. one of a..z or A..Z.
upperCase? : % -> Boolean
++ upperCase?(c) tests if c is an upper case letter,
++ i.e. one of A..Z.
lowerCase? : % -> Boolean
++ lowerCase?(c) tests if c is an lower case letter,
++ i.e. one of a..z.
alphanumeric? : % -> Boolean
++ alphanumeric?(c) tests if c is either a letter or number,
++ i.e. one of 0..9, a..z or A..Z.
-- begin new code jg
greek? : % -> Boolean
++ greek?(c) tests if c is a greek letter.
toDigit: % -> Integer
++ toDigit(c) transforms c to a digit, error if not possible.
-- end new code jg
--== add
Implementation ==> add
CC ==> CharacterClass()
import from CC
import from OF
Rep := SingleInteger -- 0..(1114112 - 1)
--cl: Record(dig: CC, hex: CC, upp: CC, low: CC, alpha: CC, alnum: CC)
:=
-- [ digit(), hexDigit(),
-- upperCase(), lowerCase(), alphabetic(), alphanumeric() ]
a = b == a =$Rep b
a < b == a <$Rep b
-- size() == 256
size() == 1114112
index n == char((n - 1)::Integer)
lookup c == (1 + ord c)::PositiveInteger
char(n : Integer) == n::%
ord c == convert(c)$Rep
-- random() == char(random(size())$Integer)
-- FIXME: limit to ASCII for now
random() == char(random(128)$Integer)
space == char 32 -- STR_ELT(" ", 0$Lisp)$Lisp
quote == char 34 -- STR_ELT("\" ", 0$Lisp)$Lisp
escape == char 95 -- STR_ELT("\_ ", 0$Lisp)$Lisp
newline == char(10)
coerce(c : %) : OutputForm == NUM2USTR(ord c)$Lisp
digit? c == member?(c pretend Character, digit())
hexDigit? c == member?(c pretend Character, hexDigit())
upperCase? c == member?(c pretend Character, upperCase())
lowerCase? c == member?(c pretend Character, lowerCase())
alphabetic? c == member?(c pretend Character, alphabetic())
alphanumeric? c == member?(c pretend Character, alphanumeric())
-- begin new code jg
infinityCharacter(): % == char 8734
greek? c == member?(c pretend Character, greek())
toDigit(c: %): Integer ==
--print blankSeparate [msg "toDigit aufgerufen mit c = ", c :: OF]
c = char "0" => 0
c = char "1" => 1
c = char "2" => 2
c = char "3" => 3
c = char "4" => 4
c = char "5" => 5
c = char "6" => 6
c = char "7" => 7
c = char "8" => 8
c = char "9" => 9
error "toDigit: not a number"
-1
-- end new code jg
latex c ==
concat("\mbox{`", concat(new(1,c pretend Character)$String,
"'}")$String)$String
char(s : String) == STR_to_CHAR(s)$Lisp
-- (#s) = 1 => s(minIndex s) pretend %
-- error "String is not a single character"
upperCase c ==
STR_ELT(PNAME(UPCASE(NUM2CHAR(ord c)$Lisp)$Lisp)$Lisp,
0$Lisp)$Lisp
lowerCase c ==
STR_ELT(PNAME(DOWNCASE(NUM2CHAR(ord c)$Lisp)$Lisp)$Lisp,
0$Lisp)$Lisp
hashUpdate!(hs : HashState, c : %) : HashState ==
update!(hs, c pretend SingleInteger)$HashState
)abbrev domain CCLASS CharacterClass
++ Author: Stephen M. Watt
++ Date Created: July 1986
++ Date extended: J. Grabmeier, 30.03.2019
++ Basic Operations: charClass
++ Related Domains: Character, Bits
++ Also See:
++ AMS Classifications:
++ Keywords:
++ Examples:
++ References:
++ Description:
++ This domain allows classes of characters to be defined and manipulated
++ efficiently.
CharacterClass : Join(SetCategory, ConvertibleTo String,
FiniteSetAggregate Character, ConvertibleTo List Character) with
charClass : String -> %
++ charClass(s) creates a character class which contains
++ exactly the characters given in the string s.
charClass : List Character -> %
++ charClass(l) creates a character class which contains
++ exactly the characters given in the list l.
digit : constant -> %
++ digit() returns the class of all characters
++ for which \spadfunFrom{digit?}{Character} is true.
hexDigit : constant -> %
++ hexDigit() returns the class of all characters for which
++ \spadfunFrom{hexDigit?}{Character} is true.
upperCase : constant -> %
++ upperCase() returns the class of all characters for which
++ \spadfunFrom{upperCase?}{Character} is true.
lowerCase : constant -> %
++ lowerCase() returns the class of all characters for which
++ \spadfunFrom{lowerCase?}{Character} is true.
alphabetic : constant -> %
++ alphabetic() returns the class of all characters for which
++ \spadfunFrom{alphabetic?}{Character} is true.
alphanumeric : constant -> %
++ alphanumeric() returns the class of all characters for which
++ \spadfunFrom{alphanumeric?}{Character} is true.
-- begin new code jg
greek : constant -> %
++ greek() returns the class of all characters for which
++ \spadfunFrom{greek?}{Character} is true.
-- end new code jg
== add
Rep := IndexedBits(0)
-- N := size()$Character
import from Character
--N := 256
N := 1024
a, b : %
digit() == charClass "0123456789"
hexDigit() == charClass "0123456789abcdefABCDEF"
upperCase() == charClass "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowerCase() == charClass "abcdefghijklmnopqrstuvwxyz"
alphabetic() == union(upperCase(), lowerCase())
alphanumeric() == union(alphabetic(), digit())
-- begin new code jg
gL : String := construct [index(u :: PositiveInteger) for u in
946..962]
gL := concat(gL, construct [index(u :: PositiveInteger) for u in
964..970] )
gL := concat(gL, construct [index(u :: PositiveInteger) for u in
914..930] )
gL := concat(gL, construct [index(u :: PositiveInteger) for u in
932..938] )
greek() == charClass gL
-- end new code jg
a = b == a =$Rep b
member?(c, a) ==
(i := ord c) < N => a(i)
false
union(a, b) == Or(a, b)
intersect (a, b) == And(a, b)
difference(a, b) == And(a, Not b)
-- FIXME: this is bogus for codes >= N
complement a == Not a
convert(cl) : String ==
construct(convert(cl)@List(Character))
convert(cl : %) : List(Character) ==
[char(i) for i in 0..N-1 | cl.i]
charClass(s : String) ==
cl := new(N, false)
for i in minIndex(s)..maxIndex(s) repeat
(j := ord s.i) >= N => error "character code too large"
cl(j) := true
cl
charClass(l : List Character) ==
cl := new(N, false)
for c in l repeat
(j := ord c) >= N => error "character code too large"
cl(j) := true
cl
coerce(cl) : OutputForm == (convert(cl)@String)::OutputForm
-- Stuff to make a legal SetAggregate view
# a == (n := 0; for i in 0..N-1 | a.i repeat n := n+1; n)
empty() : % == charClass []
set() : % == empty()
insert!(c, a) ==
(i := ord c) < N => (a(i) := true; a)
error "character code too large"
remove!(c : Character, a) ==
if(i := ord c) < N then a(i) := false
a
inspect(a) ==
for i in 0..N-1 | a.i repeat
return char i
error "Cannot take a character from an empty class."
extract!(a) ==
for i in 0..N-1 | a.i repeat
a.i := false
return char i
error "Cannot take a character from an empty class."
map(f, a) ==
b := new(N, false)
for i in 0..N-1 | a.i repeat b(ord f char i) := true
b
temp : % := new(N, false)$Rep
map!(f, a) ==
fill!(temp, false)
for i in 0..N-1 | a.i repeat temp(ord f char i) := true
copyInto!(a, temp, 0)
parts a ==
[char i for i in 0..N-1 | a.i]
)abbrev domain ISTRING IndexedString
++ Authors: Stephen Watt, Michael Monagan, Manuel Bronstein 1986 .. 1991
++ Description:
++ This domain implements low-level strings
IndexedString(mn : Integer) : Export == Implementation where
B ==> Boolean
C ==> Character
I ==> Integer
N ==> NonNegativeInteger
U ==> UniversalSegment Integer
Export ==> StringAggregate()
Implementation ==> add
-- These assume Character's Rep is Small I
Qelt ==> STR_ELT$Lisp
Qequal ==> EQUAL$Lisp
Qsetelt ==> STR_SETELT$Lisp
Qsize ==> QCSIZE$Lisp
Cheq ==> eql_SI$Lisp
Chlt ==> less_SI$Lisp
Chgt ==> greater_SI$Lisp
c : Character
cc : CharacterClass
new(n, c) == make_full_CVEC(n, c)$Lisp
empty() == make_full_CVEC(0$Lisp)$Lisp
empty?(s) == Qsize(s) = 0
#s == Qsize(s)
s = t == Qequal(s, t)
s < t == CGREATERP(t, s)$Lisp
concat(s : %, t : %) == STRCONC(s, t)$Lisp
copy s == COPY_-SEQ(s)$Lisp
insert(s : %, t : %, i : I) == concat(concat(s(mn..i-1), t), s(i..))
coerce(s : %) : OutputForm == outputForm(s pretend String)
minIndex s == mn
upperCase! s == map!(upperCase, s)
lowerCase! s == map!(lowerCase, s)
latex s == concat("\mbox{``", concat(s pretend String,
"''}"))
replace(s, sg, t) ==
l := low(sg) - mn
m := #s
n := #t
h : I := if hasHi sg then high(sg) - mn else maxIndex s - mn
l < 0 or h >= m or h < l-1 => error "index out of range"
r := new((m-(h-l+1)+n)::N, space$C)
for k in 0.. for i in 0..l-1 repeat Qsetelt(r, k, Qelt(s, i))
for k in k.. for i in 0..n-1 repeat Qsetelt(r, k, Qelt(t, i))
for k in k.. for i in h+1..m-1 repeat Qsetelt(r, k, Qelt(s, i))
r
qsetelt!(s : %, i : I, c : C) == Qsetelt(s, i - mn, c)
setelt!(s : %, i : I, c : C) ==
i < mn or i > maxIndex(s) => error "index out of range"
Qsetelt(s, i - mn, c)
substring?(part, whole, startpos) ==
np : I := Qsize part
nw : I := Qsize whole
(startpos := startpos - mn) < 0 => error "index out of bounds"
np > nw - startpos => false
for ip in 0..np-1 for iw in startpos.. repeat
not Cheq(Qelt(part, ip), Qelt(whole, iw)) => return false
true
position(s : %, t : %, startpos : I) ==
(startpos := startpos - mn) < 0 => error "index out of bounds"
startpos >= Qsize t => mn - 1
r : I := STRPOS(s, t, startpos, NIL$Lisp)$Lisp
EQ(r, NIL$Lisp)$Lisp => mn - 1
r + mn
position(c : Character, t : %, startpos : I) ==
(startpos := startpos - mn) < 0 => error "index out of bounds"
startpos >= Qsize t => mn - 1
for r in startpos..Qsize t - 1 repeat
if Cheq(Qelt(t, r), c) then return r + mn
mn - 1
position(cc : CharacterClass, t : %, startpos : I) ==
(startpos := startpos - mn) < 0 => error "index out of bounds"
startpos >= Qsize t => mn - 1
for r in startpos..Qsize t - 1 repeat
if member?(Qelt(t, r), cc) then return r + mn
mn - 1
suffix?(s, t) ==
(m := maxIndex s) > (n := maxIndex t) => false
substring?(s, t, mn + n - m)
split(s, c) ==
n := maxIndex s
for i in mn..n while s.i = c repeat 0
l := empty()$List(%)
j : Integer -- j is conditionally intialized
while i <= n and (j := position(c, s, i)) >= mn repeat
l := concat(s(i..j-1), l)
for i in j..n while s.i = c repeat 0
if i <= n then l := concat(s(i..n), l)
reverse! l
split(s, cc) ==
n := maxIndex s
for i in mn..n while member?(s.i, cc) repeat 0
l := empty()$List(%)
j : Integer -- j is conditionally intialized
while i <= n and (j := position(cc, s, i)) >= mn repeat
l := concat(s(i..j-1), l)
for i in j..n while member?(s.i, cc) repeat 0
if i <= n then l := concat(s(i..n), l)
reverse! l
leftTrim(s, cc) ==
n := maxIndex s
for i in mn .. n while member?(s.i, cc) repeat 0
s(i..n)
rightTrim(s, cc) ==
for j in maxIndex s .. mn by -1 while member?(s.j, cc) repeat 0
s(minIndex(s)..j)
concat l ==
t := new(+/[#s for s in l], space$C)
i := mn
for s in l repeat
copyInto!(t, s, i)
i := i + #s
t
copyInto!(y, x, s) ==
m := #x
n := #y
s := s - mn
s < 0 or s+m > n => error "index out of range"
RPLACSTR(y, s, m, x, 0, m)$Lisp
y
qelt(s : %, i : I) == Qelt(s, i - mn)
elt(s : %, i : I) ==
i < mn or i > maxIndex(s) => error "index out of range"
Qelt(s, i - mn)
elt(s : %, sg : U) ==
l := low(sg) - mn
h := if hasHi sg then high(sg) - mn else maxIndex s - mn
l < 0 or h >= #s => error "index out of bounds"
SUBSTRING(s, l, max(0, h-l+1))$Lisp
hashUpdate!(hs, s) == update!(hs, SXHASH(s)$Lisp)$HashState
match?(pattern, target, dontcare) ==
n := maxIndex pattern
p := position(dontcare, pattern, m := minIndex pattern)::N
p = m-1 => pattern = target
(p ~= m) and not prefix?(pattern(m..p-1), target) => false
i := p -- index into target
q := position(dontcare, pattern, p + 1)::N
while q ~= m-1 repeat
s := pattern(p+1..q-1)
i := position(s, target, i)::N
i = m-1 => return false
i := i + #s
p := q
q := position(dontcare, pattern, q + 1)::N
(p ~= n) and not suffix?(pattern(p+1..n), target) => false
true
)abbrev domain STRING String
++ Description:
++ This is the domain of character strings.
MINSTRINGINDEX ==> 1 -- as of 3/14/90.
--String() : StringCategory with
String() : Export == Implementation where
OF ==> OutputForm
Export ==> StringCategory with
ucodeToString : Integer -> %
++ ucodeToString(n) converts Unicode code point to one-character
++ string. If UTF-8 is in use the string may contain multiple
++ octets.
uentries : % -> List(SingleInteger)
++ uentries(s) converts s to a list of Unicode code points
++ encoding characters in s. It work even if lower layer
++ does not support Unicode, in such case string is treated
++ as sequence of octets using UTF-8 encoding. Consegently
++ length of returened list may be smaller than length
++ of the string in octets.
-- begin new code jg
toInteger: % -> Integer
++ toInteger(s) changes s into an integer, if it is a list of digits
++ possible after a minus sign.
toDecimalExpansion: % -> DecimalExpansion
++ toDecimalExpansion(s) changes s into a decimal expansion, if
++ it is a list of digit, possible after a minus sign,
++ containing at most one comma, but is allowed to contain
++ arbitrary many blanks and periods.
-- end new code jg
-- == IndexedString(MINSTRINGINDEX) add
Implementation ==> IndexedString(MINSTRINGINDEX) add
import OutputForm
-- begin new code jg
toInteger(s: %): Integer ==
lc : List Character := parts s
empty? lc => 0
negative? : Boolean := first(lc) = char "-"
if negative? then lc := rest lc
res : Integer := 0
for c in lc repeat
if c ~= char "." then
res := 10 * res + toDigit(c)$Character
if negative? then -res else res
toDecimalExpansion(s: %): DecimalExpansion ==
lc : List Character := parts s
empty? lc => 0
negative? : Boolean := first(lc) = char "-"
if negative? then lc := rest lc
lc' : List Character := copy lc
res : DecimalExpansion := 0
ten : DecimalExpansion := 10 :: DecimalExpansion
oneTenth : DecimalExpansion := 1/ten
for c in lc repeat
if c = char "," then
lc' := rest lc'
break
if c ~= char "." then
res := ten * res + toDigit(c) :: DecimalExpansion
lc' := rest lc'
lc' := reverse lc'
res' : DecimalExpansion := 0
for c in lc' repeat
if c ~= char "." then
res' := oneTenth * (res' + toDigit(c) :: DecimalExpansion)
res := res+res'
if negative? then -res else res
-- end new code jg
ucodeToString(n : Integer) : % == NUM2USTR(n)$Lisp
uentries(s : %) : List(SingleInteger) == UENTRIES(s)$Lisp
string n == STRINGIMAGE(n)$Lisp
OMwrite(dev : OpenMathDevice, x : %, wholeObj : Boolean) : Void ==
if wholeObj then
OMputObject(dev)
OMputString(dev, x pretend String)
if wholeObj then
OMputEndObject(dev)
convert(x : %) : InputForm == x pretend InputForm
qelt(s : %, i : Integer) == STR_ELT1(s, i)$Lisp
qsetelt!(s : %, i : Integer, c : Character) == STR_SETELT1(s, i, c)$Lisp
)abbrev category STRICAT StringCategory
-- Note that StringCategory is built into the old compiler
-- redundant SetCategory added to help A# compiler
++ Description:
++ A category for string-like objects
StringCategory() : Category == Join(StringAggregate(), SetCategory, OpenMath)
with
string : Integer -> %
++ string(i) returns the decimal representation of i as a string.
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.