From 8350454b69670747ad0ec21f6a6d2ef2d49ea97a Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Mon, 22 Jul 2024 03:59:51 +0200 Subject: [PATCH 1/2] added try .. then .. clause --- M2/Macaulay2/d/binding.d | 4 ++++ M2/Macaulay2/d/convertr.d | 7 ++++--- M2/Macaulay2/d/evaluate.d | 13 +++++-------- M2/Macaulay2/d/parse.d | 7 ++++--- M2/Macaulay2/d/parser.d | 12 ++++++------ M2/Macaulay2/m2/basictests/A01.m2 | 10 +++++++--- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/M2/Macaulay2/d/binding.d b/M2/Macaulay2/d/binding.d index 9a151fd38f7..ddd8d3416c6 100644 --- a/M2/Macaulay2/d/binding.d +++ b/M2/Macaulay2/d/binding.d @@ -889,6 +889,10 @@ export bind(e:ParseTree,dictionary:Dictionary):void := ( -- i.alternate = bindnewdictionary(i.alternate,dictionary); bind(i.alternate,dictionary); ) + is i:TryThen do ( + bind(i.primary,dictionary); + bind(i.sequel,dictionary); + ) is i:TryThenElse do ( bind(i.primary,dictionary); bind(i.sequel,dictionary); diff --git a/M2/Macaulay2/d/convertr.d b/M2/Macaulay2/d/convertr.d index 7548b1badd8..cb6c30167f1 100644 --- a/M2/Macaulay2/d/convertr.d +++ b/M2/Macaulay2/d/convertr.d @@ -432,9 +432,10 @@ export convert(e:ParseTree):Code := ( pos := treePosition(e); nd := nestingDepth(sym.frameID,token.dictionary); Code(localSymbolClosureCode(nd,sym,pos))) - is i:TryThenElse do Code(tryCode(convert(i.primary),convert(i.sequel),convert(i.alternate),treePosition(e))) - is i:TryElse do Code(tryCode(convert(i.primary),NullCode,convert(i.alternate),treePosition(e))) - is i:Try do Code(tryCode(convert(i.primary),NullCode,NullCode,treePosition(e))) + is i:TryThenElse do Code(tryCode(convert(i.primary), convert(i.sequel), convert(i.alternate), treePosition(e))) + is i:TryThen do Code(tryCode(convert(i.primary), convert(i.sequel), NullCode, treePosition(e))) + is i:TryElse do Code(tryCode(convert(i.primary), NullCode, convert(i.alternate), treePosition(e))) + is i:Try do Code(tryCode(convert(i.primary), NullCode, NullCode, treePosition(e))) is i:Catch do Code(catchCode(convert(i.primary),treePosition(e))) is u:Postfix do Code(unaryCode(u.Operator.entry.postfix,convert(u.lhs),treePosition(e))) is d:dummy do dummyCode diff --git a/M2/Macaulay2/d/evaluate.d b/M2/Macaulay2/d/evaluate.d index 54b7c2b7512..a512127458d 100644 --- a/M2/Macaulay2/d/evaluate.d +++ b/M2/Macaulay2/d/evaluate.d @@ -1474,14 +1474,11 @@ export evalraw(c:Code):Expr := ( is c:globalSymbolClosureCode do return Expr(SymbolClosure(globalFrame,c.symbol)) is c:threadSymbolClosureCode do return Expr(SymbolClosure(threadFrame,c.symbol)) is c:tryCode do ( - p := tryEval(c.code); - if tryEvalSuccess - then ( - when p is Error do p - else if c.thenClause == NullCode then p - else eval(c.thenClause)) - else ( - eval(c.elseClause))) + ret := tryEval(c.code); + if tryEvalSuccess then + when ret is Error do ret + else if c.thenClause == NullCode then ret else eval(c.thenClause) + else if c.elseClause == NullCode then nullE else eval(c.elseClause)) is c:catchCode do ( p := eval(c.code); when p is err:Error do if err.message == throwMessage then err.value else p diff --git a/M2/Macaulay2/d/parse.d b/M2/Macaulay2/d/parse.d index affb860699b..8cc08234db0 100644 --- a/M2/Macaulay2/d/parse.d +++ b/M2/Macaulay2/d/parse.d @@ -127,9 +127,10 @@ export For := {+ forToken:Token, variable:ParseTree, inClause:ParseTree, fromCla export WhileDo := {+ whileToken:Token, predicate:ParseTree, dotoken:Token, doClause:ParseTree}; export WhileList := {+ whileToken:Token, predicate:ParseTree, listtoken:Token, listClause:ParseTree}; export WhileListDo := {+ whileToken:Token, predicate:ParseTree, listtoken:Token, listClause:ParseTree, dotoken:Token, doClause:ParseTree }; -export TryElse := {+ tryToken:Token, primary:ParseTree, elseToken:Token, alternate:ParseTree}; export TryThenElse := {+ tryToken:Token, primary:ParseTree, thenToken:Token, sequel:ParseTree, elseToken:Token, alternate:ParseTree}; -export Try := {+ tryToken:Token, primary:ParseTree}; +export TryThen := {+ tryToken:Token, primary:ParseTree, thenToken:Token, sequel:ParseTree}; +export TryElse := {+ tryToken:Token, primary:ParseTree, elseToken:Token, alternate:ParseTree}; +export Try := {+ tryToken:Token, primary:ParseTree}; export Catch := {+ catchToken:Token, primary:ParseTree}; export IfThen := {+ ifToken:Token, predicate:ParseTree, thenclause:ParseTree }; export IfThenElse := {+ ifToken:Token, predicate:ParseTree, thenclause:ParseTree, elseClause:ParseTree}; @@ -150,7 +151,7 @@ export ParseTree := ( Token or Adjacent or Binary or Unary or Postfix or Parentheses or EmptyParentheses or IfThen or IfThenElse or Quote or GlobalQuote or ThreadQuote or LocalQuote - or TryThenElse or TryElse or Try or Catch or WhileDo or For or WhileList or WhileListDo or Arrow or New or dummy ); + or TryThenElse or TryThen or TryElse or Try or Catch or WhileDo or For or WhileList or WhileListDo or Arrow or New or dummy ); -- Code diff --git a/M2/Macaulay2/d/parser.d b/M2/Macaulay2/d/parser.d index 8295240bd92..33178ac16ab 100644 --- a/M2/Macaulay2/d/parser.d +++ b/M2/Macaulay2/d/parser.d @@ -487,9 +487,7 @@ export unarytry(tryToken:Token,file:TokenFile,prec:int,obeylines:bool):ParseTree elseClause := parse(file,elseW.parse.unaryStrength,obeylines); if elseClause == errorTree then return errorTree; accumulate(ParseTree(TryThenElse(tryToken,primary,thenToken,thenClause,elseToken,elseClause)),file,prec,obeylines)) - else ( - printErrorMessage(tryToken,"syntax error : expected 'else' to match this 'try'"); - errorTree)) + else accumulate(ParseTree(TryThen(tryToken,primary,thenToken,thenClause)),file,prec,obeylines)) else accumulate(ParseTree(Try(tryToken,primary)),file,prec,obeylines)); export unarycatch(catchToken:Token,file:TokenFile,prec:int,obeylines:bool):ParseTree := ( primary := parse(file,catchToken.word.parse.unaryStrength,obeylines); @@ -532,6 +530,7 @@ export treePosition(e:ParseTree):Position := ( is ee:EmptyParentheses do return position(ee.left) is i:IfThen do return position(i.ifToken) is i:TryThenElse do return position(i.tryToken) + is i:TryThen do return position(i.tryToken) is i:TryElse do return position(i.tryToken) is i:Try do return position(i.tryToken) is i:Catch do return position(i.catchToken) @@ -564,9 +563,10 @@ export size(e:ParseTree):int := ( is x:EmptyParentheses do Ccode(int,"sizeof(*",x,")") + size(x.left) + size(x.right) is x:IfThen do Ccode(int,"sizeof(*",x,")") + size(x.ifToken) + size(x.predicate) + size(x.thenclause) is x:IfThenElse do Ccode(int,"sizeof(*",x,")") + size(x.ifToken) + size(x.predicate) + size(x.thenclause) + size(x.elseClause) - is x:TryThenElse do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + size(x.thenToken) + size(x.sequel) + size(x.elseToken) + size(x.alternate) - is x:TryElse do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + size(x.elseToken) + size(x.alternate) - is x:Try do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + is x:TryThenElse do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + size(x.thenToken) + size(x.sequel) + size(x.elseToken) + size(x.alternate) + is x:TryThen do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + size(x.thenToken) + size(x.sequel) + is x:TryElse do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) + size(x.elseToken) + size(x.alternate) + is x:Try do Ccode(int,"sizeof(*",x,")") + size(x.tryToken) + size(x.primary) is x:Catch do Ccode(int,"sizeof(*",x,")") + size(x.catchToken) + size(x.primary) is x:For do Ccode(int,"sizeof(*",x,")")+ size(x.forToken) + size(x.variable) + size(x.inClause) + size(x.fromClause) + size(x.toClause) + size(x.whenClause) + size(x.listClause) + size(x.doClause) is x:WhileDo do Ccode(int,"sizeof(*",x,")") + size(x.whileToken) + size(x.predicate) + size(x.dotoken) + size(x.doClause) diff --git a/M2/Macaulay2/m2/basictests/A01.m2 b/M2/Macaulay2/m2/basictests/A01.m2 index 210cd35e955..4e8c518a913 100644 --- a/M2/Macaulay2/m2/basictests/A01.m2 +++ b/M2/Macaulay2/m2/basictests/A01.m2 @@ -55,11 +55,15 @@ assert( not not true ) assert( not true === false ) assert( not false === true ) --- test try -assert( try error "" else true ) +-- test try .. then .. else clauses +assert( true === try 1/0 then false else true ) +assert( null === try 1/0 then false ) +assert( true === try 1/0 else true ) +assert( null === try 1/0 ) +assert( try true then true else false ) assert( try true else false ) +assert( try true then true ) assert( try true ) -assert( null === try error "" ) --i = 5 --try i := 6 else i :=7 --assert(i === 5) From 44e6f0ec6b16df62afc7640b0cc829053e713ba8 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Mon, 22 Jul 2024 04:10:43 +0200 Subject: [PATCH 2/2] documented the try .. then .. clause --- M2/Macaulay2/packages/Macaulay2Doc/ov_language.m2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/M2/Macaulay2/packages/Macaulay2Doc/ov_language.m2 b/M2/Macaulay2/packages/Macaulay2Doc/ov_language.m2 index 184d5329377..a74937d7a60 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/ov_language.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/ov_language.m2 @@ -745,6 +745,10 @@ document { PARA{}, "The clause '", TT "then y", "' may be omitted, in which case the return value is the value returned by ", TT "x", ", if there is no error or alarm.", PARA{}, + "The clause '", TT "else z", "' may be omitted, + in which case the return value is the value returned by ", TT "y", ", + unless an error or alarm occurs, in which case ", TO "null", " is returned.", + PARA{}, "The clauses '", TT "then y else z", "' may both be omitted, in which case the return value is the value returned by ", TT "x", ", unless an error or alarm occurs, in which case ", TO "null", " is returned.", PARA{},