1 2 3 4 | ||
Editor: Bill Page
Time: 2008/09/17 09:26:42 GMT-7 |
||
Note: export new function: parse |
added:
Add a new export for 'parse'.
\begin{spad}
)abbrev domain INFORM InputForm
++ Parser forms
++ Author: Manuel Bronstein
++ Date Created: ???
++ Date Last Updated: 19 April 1991
++ Description:
++ Domain of parsed forms which can be passed to the interpreter.
++ This is also the interface between algebra code and facilities
++ in the interpreter.
--)boot $noSubsumption := true
InputForm():
Join(SExpressionCategory(String,Symbol,Integer,DoubleFloat,OutputForm),
ConvertibleTo SExpression) with
interpret: % -> Any
++ interpret(f) passes f to the interpreter.
convert : SExpression -> %
++ convert(s) makes s into an input form.
binary : (%, List %) -> %
++ \spad{binary(op, [a1,...,an])} returns the input form
++ corresponding to \spad{a1 op a2 op ... op an}.
function : (%, List Symbol, Symbol) -> %
++ \spad{function(code, [x1,...,xn], f)} returns the input form
++ corresponding to \spad{f(x1,...,xn) == code}.
lambda : (%, List Symbol) -> %
++ \spad{lambda(code, [x1,...,xn])} returns the input form
++ corresponding to \spad{(x1,...,xn) +-> code} if \spad{n > 1},
++ or to \spad{x1 +-> code} if \spad{n = 1}.
"+" : (%, %) -> %
++ \spad{a + b} returns the input form corresponding to \spad{a + b}.
"*" : (%, %) -> %
++ \spad{a * b} returns the input form corresponding to \spad{a * b}.
"/" : (%, %) -> %
++ \spad{a / b} returns the input form corresponding to \spad{a / b}.
"**" : (%, NonNegativeInteger) -> %
++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}.
"**" : (%, Integer) -> %
++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}.
0 : constant -> %
++ \spad{0} returns the input form corresponding to 0.
1 : constant -> %
++ \spad{1} returns the input form corresponding to 1.
flatten : % -> %
++ flatten(s) returns an input form corresponding to s with
++ all the nested operations flattened to triples using new
++ local variables.
++ If s is a piece of code, this speeds up
++ the compilation tremendously later on.
unparse : % -> String
++ unparse(f) returns a string s such that the parser
++ would transform s to f.
++ Error: if f is not the parsed form of a string.
parse : String -> %
++ parse(s) is the inverse of unparse. It parses a
++ string to InputForm
declare : List % -> Symbol
++ declare(t) returns a name f such that f has been
++ declared to the interpreter to be of type t, but has
++ not been assigned a value yet.
++ Note: t should be created as \spad{devaluate(T)$Lisp} where T is the
++ actual type of f (this hack is required for the case where
++ T is a mapping type).
compile : (Symbol, List %) -> Symbol
++ \spad{compile(f, [t1,...,tn])} forces the interpreter to compile
++ the function f with signature \spad{(t1,...,tn) -> ?}.
++ returns the symbol f if successful.
++ Error: if f was not defined beforehand in the interpreter,
++ or if the ti's are not valid types, or if the compiler fails.
== SExpression add
Rep := SExpression
mkProperOp: Symbol -> %
strsym : % -> String
tuplify : List Symbol -> %
flatten0 : (%, Symbol, NonNegativeInteger) ->
Record(lst: List %, symb:%)
0 == convert(0::Integer)
1 == convert(1::Integer)
convert(x:%):SExpression == x pretend SExpression
convert(x:SExpression):% == x
conv(ll : List %): % ==
convert(ll pretend List SExpression)$SExpression pretend %
lambda(f,l) == conv([convert("+->"::Symbol),tuplify l,f]$List(%))
interpret x ==
v := interpret(x)$Lisp
mkObj(unwrap(objVal(v)$Lisp)$Lisp, objMode(v)$Lisp)$Lisp
convert(x:DoubleFloat):% ==
zero? x => 0
-- one? x => 1
(x = 1) => 1
convert(x)$Rep
flatten s ==
-- will not compile if I use 'or'
atom? s => s
every?(atom?,destruct s)$List(%) => s
sy := new()$Symbol
n:NonNegativeInteger := 0
l2 := [flatten0(x, sy, n := n + 1) for x in rest(l := destruct s)]
conv(concat(convert("SEQ"::Symbol)@%,
concat(concat [u.lst for u in l2], conv(
[convert("exit"::Symbol)@%, 1$%, conv(concat(first l,
[u.symb for u in l2]))@%]$List(%))@%)))@%
flatten0(s, sy, n) ==
atom? s => [nil(), s]
a := convert(concat(string sy, convert(n)@String)::Symbol)@%
l2 := [flatten0(x, sy, n := n+1) for x in rest(l := destruct s)]
[concat(concat [u.lst for u in l2], conv([convert(
"LET"::Symbol)@%, a, conv(concat(first l,
[u.symb for u in l2]))@%]$List(%))@%), a]
strsym s ==
string? s => string s
symbol? s => string symbol s
error "strsym: form is neither a string or symbol"
unparse x ==
atom?(s:% := form2String(x)$Lisp) => strsym s
concat [strsym a for a in destruct s]
parse(s:String):% ==
ncParseFromString(s)$Lisp
declare signature ==
declare(name := new()$Symbol, signature)$Lisp
name
compile(name, types) ==
symbol car cdr car
selectLocalMms(mkProperOp name, convert(name)@%,
types, nil$List(%))$Lisp
mkProperOp name ==
op := mkAtree(nme := convert(name)@%)$Lisp
transferPropsToNode(nme, op)$Lisp
convert op
binary(op, args) ==
(n := #args) < 2 => error "Need at least 2 arguments"
n = 2 => convert([op, first args, last args]$List(%))
convert([op, first args, binary(op, rest args)]$List(%))
tuplify l ==
empty? rest l => convert first l
conv
concat(convert("Tuple"::Symbol), [convert x for x in l]$List(%))
function(f, l, name) ==
nn := convert(new(1 + #l, convert(nil()$List(%)))$List(%))@%
conv([convert("DEF"::Symbol), conv(cons(convert(name)@%,
[convert(x)@% for x in l])), nn, nn, f]$List(%))
s1 + s2 ==
s1 = 0 => s2
s2 = 0 => s1
conv [convert("+"::Symbol), s1, s2]$List(%)
s1 * s2 ==
s1 = 0 or s2 = 0 => 0
s1 = 1 => s2
s2 = 1 => s1
conv [convert("*"::Symbol), s1, s2]$List(%)
s1:% ** n:Integer ==
s1 = 0 and n > 0 => 0
s1 = 1 or zero? n => 1
-- one? n => s1
(n = 1) => s1
conv [convert("**"::Symbol), s1, convert n]$List(%)
s1:% ** n:NonNegativeInteger == s1 ** (n::Integer)
s1 / s2 ==
s2 = 1 => s1
conv [convert("/"::Symbol), s1, s2]$List(%)
\end{spad}
Test
\begin{axiom}
parse("sin x + 1")
\end{axiom}
Domain of parsed forms which can be passed to the interpreter. This is also the interface between algebra code and facilities in the interpreter.
)show InputForm
InputForm is a domain constructor Abbreviation for InputForm is INFORM This constructor is not exposed in this frame. Issue )edit /usr/local/lib/axiom/target/x86_64-unknown-linux/../../src/algebra/INFORM.spad to see algebra source code for INFORM
------------------------------- Operations -------------------------------- #? : % -> Integer ?*? : (%,%) -> % ?**? : (%,Integer) -> % ?+? : (%,%) -> % ?/? : (%,%) -> % ?=? : (%,%) -> Boolean 1 : () -> % 0 : () -> % atom? : % -> Boolean binary : (%,List %) -> % car : % -> % cdr : % -> % coerce : % -> OutputForm convert : SExpression -> % convert : % -> SExpression convert : OutputForm -> % convert : DoubleFloat -> % convert : Integer -> % convert : Symbol -> % convert : String -> % convert : List % -> % declare : List % -> Symbol destruct : % -> List % ?.? : (%,List Integer) -> % ?.? : (%,Integer) -> % eq : (%,%) -> Boolean expr : % -> OutputForm flatten : % -> % float : % -> DoubleFloat float? : % -> Boolean hash : % -> SingleInteger integer : % -> Integer integer? : % -> Boolean interpret : % -> Any lambda : (%,List Symbol) -> % latex : % -> String list? : % -> Boolean null? : % -> Boolean pair? : % -> Boolean string : % -> String string? : % -> Boolean symbol : % -> Symbol symbol? : % -> Boolean unparse : % -> String ?~=? : (%,%) -> Boolean ?**? : (%,NonNegativeInteger) -> % compile : (Symbol,List %) -> Symbol function : (%,List Symbol,Symbol) -> %
Add a new export for parse
.
)abbrev domain INFORM InputForm ++ Parser forms ++ Author: Manuel Bronstein ++ Date Created: ??? ++ Date Last Updated: 19 April 1991 ++ Description: ++ Domain of parsed forms which can be passed to the interpreter. ++ This is also the interface between algebra code and facilities ++ in the interpreter.
--)boot $noSubsumption := true
InputForm(): Join(SExpressionCategory(String,Symbol,Integer,DoubleFloat,OutputForm), ConvertibleTo SExpression) with interpret: % -> Any ++ interpret(f) passes f to the interpreter. convert : SExpression -> % ++ convert(s) makes s into an input form. binary : (%, List %) -> % ++ \spad{binary(op, [a1,...,an])} returns the input form ++ corresponding to \spad{a1 op a2 op ... op an}. function : (%, List Symbol, Symbol) -> % ++ \spad{function(code, [x1,...,xn], f)} returns the input form ++ corresponding to \spad{f(x1,...,xn) == code}. lambda : (%, List Symbol) -> % ++ \spad{lambda(code, [x1,...,xn])} returns the input form ++ corresponding to \spad{(x1,...,xn) +-> code} if \spad{n > 1}, ++ or to \spad{x1 +-> code} if \spad{n = 1}. "+" : (%, %) -> % ++ \spad{a + b} returns the input form corresponding to \spad{a + b}. "*" : (%, %) -> % ++ \spad{a * b} returns the input form corresponding to \spad{a * b}. "/" : (%, %) -> % ++ \spad{a / b} returns the input form corresponding to \spad{a / b}. "**" : (%, NonNegativeInteger) -> % ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}. "**" : (%, Integer) -> % ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}. 0 : constant -> % ++ \spad{0} returns the input form corresponding to 0. 1 : constant -> % ++ \spad{1} returns the input form corresponding to 1. flatten : % -> % ++ flatten(s) returns an input form corresponding to s with ++ all the nested operations flattened to triples using new ++ local variables. ++ If s is a piece of code, this speeds up ++ the compilation tremendously later on. unparse : % -> String ++ unparse(f) returns a string s such that the parser ++ would transform s to f. ++ Error: if f is not the parsed form of a string. parse : String -> % ++ parse(s) is the inverse of unparse. It parses a ++ string to InputForm declare : List % -> Symbol ++ declare(t) returns a name f such that f has been ++ declared to the interpreter to be of type t, but has ++ not been assigned a value yet. ++ Note: t should be created as \spad{devaluate(T)$Lisp} where T is the ++ actual type of f (this hack is required for the case where ++ T is a mapping type). compile : (Symbol, List %) -> Symbol ++ \spad{compile(f, [t1,...,tn])} forces the interpreter to compile ++ the function f with signature \spad{(t1,...,tn) -> ?}. ++ returns the symbol f if successful. ++ Error: if f was not defined beforehand in the interpreter, ++ or if the ti's are not valid types, or if the compiler fails. == SExpression add Rep := SExpression
mkProperOp: Symbol -> % strsym : % -> String tuplify : List Symbol -> % flatten0 : (%, Symbol, NonNegativeInteger) -> Record(lst: List %, symb:%)
0 == convert(0::Integer) 1 == convert(1::Integer) convert(x:%):SExpression == x pretend SExpression convert(x:SExpression):% == x
conv(ll : List %): % == convert(ll pretend List SExpression)$SExpression pretend %
lambda(f,l) == conv([convert("+->"::Symbol),tuplify l,f]$List(%))
interpret x == v := interpret(x)$Lisp mkObj(unwrap(objVal(v)$Lisp)$Lisp, objMode(v)$Lisp)$Lisp
convert(x:DoubleFloat):% == zero? x => 0 -- one? x => 1 (x = 1) => 1 convert(x)$Rep
flatten s == -- will not compile if I use 'or' atom? s => s every?(atom?,destruct s)$List(%) => s sy := new()$Symbol n:NonNegativeInteger := 0 l2 := [flatten0(x, sy, n := n + 1) for x in rest(l := destruct s)] conv(concat(convert("SEQ"::Symbol)@%, concat(concat [u.lst for u in l2], conv( [convert("exit"::Symbol)@%, 1$%, conv(concat(first l, [u.symb for u in l2]))@%]$List(%))@%)))@%
flatten0(s, sy, n) == atom? s => [nil(), s] a := convert(concat(string sy, convert(n)@String)::Symbol)@% l2 := [flatten0(x, sy, n := n+1) for x in rest(l := destruct s)] [concat(concat [u.lst for u in l2], conv([convert( "LET"::Symbol)@%, a, conv(concat(first l, [u.symb for u in l2]))@%]$List(%))@%), a]
strsym s == string? s => string s symbol? s => string symbol s error "strsym: form is neither a string or symbol"
unparse x == atom?(s:% := form2String(x)$Lisp) => strsym s concat [strsym a for a in destruct s]
parse(s:String):% == ncParseFromString(s)$Lisp
declare signature == declare(name := new()$Symbol, signature)$Lisp name
compile(name, types) == symbol car cdr car selectLocalMms(mkProperOp name, convert(name)@%, types, nil$List(%))$Lisp
mkProperOp name == op := mkAtree(nme := convert(name)@%)$Lisp transferPropsToNode(nme, op)$Lisp convert op
binary(op, args) == (n := #args) < 2 => error "Need at least 2 arguments" n = 2 => convert([op, first args, last args]$List(%)) convert([op, first args, binary(op, rest args)]$List(%))
tuplify l == empty? rest l => convert first l conv concat(convert("Tuple"::Symbol), [convert x for x in l]$List(%))
function(f, l, name) == nn := convert(new(1 + #l, convert(nil()$List(%)))$List(%))@% conv([convert("DEF"::Symbol), conv(cons(convert(name)@%, [convert(x)@% for x in l])), nn, nn, f]$List(%))
s1 + s2 == s1 = 0 => s2 s2 = 0 => s1 conv [convert("+"::Symbol), s1, s2]$List(%)
s1 * s2 == s1 = 0 or s2 = 0 => 0 s1 = 1 => s2 s2 = 1 => s1 conv [convert("*"::Symbol), s1, s2]$List(%)
s1:% ** n:Integer == s1 = 0 and n > 0 => 0 s1 = 1 or zero? n => 1 -- one? n => s1 (n = 1) => s1 conv [convert("**"::Symbol), s1, convert n]$List(%)
s1:% ** n:NonNegativeInteger == s1 ** (n::Integer)
s1 / s2 == s2 = 1 => s1 conv [convert("/"::Symbol), s1, s2]$List(%)
Compiling FriCAS source code from file /var/zope2/var/LatexWiki/6679376400046902071-25px002.spad using old system compiler. INFORM abbreviates domain InputForm ------------------------------------------------------------------------ initializing NRLIB INFORM for InputForm compiling into NRLIB INFORM compiling exported Zero : () -> $ Time: 0.10 SEC.
compiling exported One : () -> $ Time: 0.01 SEC.
compiling exported convert : $ -> SExpression INFORM;convert;$Se;3 is replaced by x Time: 0 SEC.
compiling exported convert : SExpression -> $ INFORM;convert;Se$;4 is replaced by x Time: 0 SEC.
compiling local conv : List $ -> $ Time: 0.05 SEC.
compiling exported lambda : ($,List Symbol) -> $ Time: 0.10 SEC.
compiling exported interpret : $ -> Any Time: 0 SEC.
compiling exported convert : DoubleFloat -> $ Time: 0 SEC.
compiling exported flatten : $ -> $ Time: 0.17 SEC.
compiling local flatten0 : ($,Symbol,NonNegativeInteger) -> Record(lst: List $,symb: $) Time: 0.08 SEC.
compiling local strsym : $ -> String Time: 0.01 SEC.
compiling exported unparse : $ -> String Time: 0.09 SEC.
compiling exported parse : String -> $ INFORM;parse;S$;13 is replaced by ncParseFromString Time: 0 SEC.
compiling exported declare : List $ -> Symbol Time: 0 SEC.
compiling exported compile : (Symbol,List $) -> Symbol Time: 0.01 SEC.
compiling local mkProperOp : Symbol -> $ Time: 0 SEC.
compiling exported binary : ($,List $) -> $ Time: 0.01 SEC.
compiling local tuplify : List Symbol -> $ Time: 0.02 SEC.
compiling exported function : ($,List Symbol,Symbol) -> $ Time: 0.10 SEC.
compiling exported + : ($,$) -> $ Time: 0.01 SEC.
compiling exported * : ($,$) -> $ Time: 0.01 SEC.
compiling exported ** : ($,Integer) -> $ Time: 0.01 SEC.
compiling exported ** : ($,NonNegativeInteger) -> $ Time: 0 SEC.
compiling exported / : ($,$) -> $ Time: 0.01 SEC.
(time taken in buildFunctor: 1)
;;; *** |InputForm| REDEFINED
;;; *** |InputForm| REDEFINED Time: 0.01 SEC.
Warnings: [1] conv: pretend$ -- should replace by @
Cumulative Statistics for Constructor InputForm Time: 0.80 seconds
finalizing NRLIB INFORM Processing InputForm for Browser database: --------(interpret ((Any) %))--------- --------(convert (% (SExpression)))--------- --------(binary (% % (List %)))--------- --------(function (% % (List (Symbol)) (Symbol)))--------- --------(lambda (% % (List (Symbol))))--------- --------(+ (% % %))--------- --------(* (% % %))--------- --------(/ (% % %))--------- --------(** (% % (NonNegativeInteger)))--------- --------(** (% % (Integer)))--------- --------((Zero) (%) constant)--------- --------((One) (%) constant)--------- --------(flatten (% %))--------- --------(unparse ((String) %))--------- --------(parse (% (String)))--------- --------(declare ((Symbol) (List %)))--------- --------(compile ((Symbol) (Symbol) (List %)))--------- --------constructor--------- ------------------------------------------------------------------------ InputForm is now explicitly exposed in frame initial InputForm will be automatically loaded when needed from /var/zope2/var/LatexWiki/INFORM.NRLIB/code
Test
parse("sin x + 1")
(1) |