-
-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tweak some error messages to be more like WMA... #1094
Changes from 4 commits
58ed3e8
7667677
73b99f0
d8f3987
c669876
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
from mathics.core.builtin import BinaryOperator, Builtin | ||
from mathics.core.convert.expression import to_mathics_list | ||
from mathics.core.convert.python import from_python | ||
from mathics.core.evaluation import Evaluation | ||
from mathics.core.exceptions import ( | ||
InvalidLevelspecError, | ||
MessageException, | ||
|
@@ -580,39 +581,74 @@ class First(Builtin): | |
<dl> | ||
<dt>'First[$expr$]' | ||
<dd>returns the first element in $expr$. | ||
|
||
<dt>'First[$expr$, $def$]' | ||
<dd>returns the first element in $expr$ if it exists or $def$ otherwise. | ||
</dl> | ||
|
||
'First[$expr$]' is equivalent to '$expr$[[1]]'. | ||
|
||
>> First[{a, b, c}] | ||
= a | ||
|
||
The first argument need not be a list: | ||
>> First[a + b + c] | ||
= a | ||
|
||
However, the first argument must be Nonatomic when there is a single argument: | ||
>> First[x] | ||
: Nonatomic expression expected. | ||
: Nonatomic expression expected at position 1 in First[x]. | ||
= First[x] | ||
|
||
Or if it is not, but a second default argument is provided, that is \ | ||
evaluated and returned: | ||
|
||
>> First[10, 1+2] | ||
= 3 | ||
|
||
>> First[{}] | ||
: {} has zero length and no first element. | ||
= First[{}] | ||
|
||
As before, the first argument is empty, but a default argument is given, \ | ||
evaluate and return the second argument: | ||
>> First[{}, 1+2] | ||
= 3 | ||
""" | ||
|
||
attributes = A_HOLD_REST | A_PROTECTED | ||
messages = { | ||
"normal": "Nonatomic expression expected.", | ||
"argt": "First called with `1` arguments; 1 or 2 arguments are expected.", | ||
"normal": "Nonatomic expression expected at position 1 in `1`.", | ||
"nofirst": "`1` has zero length and no first element.", | ||
} | ||
summary_text = "first element of a list or expression" | ||
|
||
def eval(self, expr, evaluation): | ||
"First[expr_]" | ||
# FIXME: the code and the code for Last are similar and can be DRY'd | ||
def eval(self, expr, evaluation: Evaluation, expression: Expression): | ||
"First[expr__]" | ||
|
||
if isinstance(expr, Atom): | ||
evaluation.message("First", "normal") | ||
evaluation.message("First", "normal", expression) | ||
return | ||
if len(expr.elements) == 0: | ||
expr_len = len(expr.elements) | ||
if expr_len == 0: | ||
evaluation.message("First", "nofirst", expr) | ||
return | ||
if expr_len > 2 and expr.head is SymbolSequence: | ||
evaluation.message("First", "argt", expr_len) | ||
return | ||
|
||
first_elem = expr.elements[0] | ||
|
||
if expr.head == SymbolSequence or ( | ||
not isinstance(expr, ListExpression) | ||
and len == 2 | ||
and isinstance(first_elem, Atom) | ||
): | ||
return expr.elements[1].evaluate(evaluation) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a comment: to call the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok - thanks. Will remove the explicit call. |
||
|
||
return expr.elements[0] | ||
return first_elem | ||
|
||
|
||
class FirstCase(Builtin): | ||
|
@@ -813,37 +849,74 @@ class Last(Builtin): | |
<dl> | ||
<dt>'Last[$expr$]' | ||
<dd>returns the last element in $expr$. | ||
|
||
<dt>'Last[$expr$, $def$]' | ||
<dd>returns the last element in $expr$ if it exists or $def$ otherwise. | ||
</dl> | ||
|
||
'Last[$expr$]' is equivalent to '$expr$[[-1]]'. | ||
|
||
>> Last[{a, b, c}] | ||
= c | ||
>> Last[x] | ||
: Nonatomic expression expected. | ||
= Last[x] | ||
|
||
The first argument need not be a list: | ||
>> Last[a + b + c] | ||
= c | ||
|
||
However, the first argument must be Nonatomic when there is a single argument: | ||
>> Last[10] | ||
: Nonatomic expression expected at position 1 in Last[10]. | ||
= Last[10] | ||
|
||
Or if it is not, but a second default argument is provided, that is \ | ||
evaluated and returned: | ||
|
||
>> Last[10, 1+2] | ||
= 3 | ||
|
||
|
||
>> Last[{}] | ||
: {} has zero length and no last element. | ||
= Last[{}] | ||
|
||
As before, the first argument is empty, but since default argument is given, \ | ||
evaluate and return the second argument: | ||
>> Last[{}, 1+2] | ||
= 3 | ||
""" | ||
|
||
attributes = A_HOLD_REST | A_PROTECTED | ||
messages = { | ||
"normal": "Nonatomic expression expected.", | ||
"argt": "Last called with `1` arguments; 1 or 2 arguments are expected.", | ||
"normal": "Nonatomic expression expected at position 1 in `1`.", | ||
"nolast": "`1` has zero length and no last element.", | ||
} | ||
summary_text = "last element of a list or expression" | ||
|
||
def eval(self, expr, evaluation): | ||
"Last[expr_]" | ||
# FIXME: the code and the code for First are similar and can be DRY'd | ||
def eval(self, expr, evaluation: Evaluation, expression: Expression): | ||
"Last[expr__]" | ||
|
||
if isinstance(expr, Atom): | ||
evaluation.message("Last", "normal") | ||
evaluation.message("Last", "normal", expression) | ||
return | ||
if len(expr.elements) == 0: | ||
expr_len = len(expr.elements) | ||
if expr_len == 0: | ||
evaluation.message("Last", "nolast", expr) | ||
return | ||
if expr_len > 2 and expr.head is SymbolSequence: | ||
evaluation.message("Last", "argt", expr_len) | ||
return | ||
|
||
last_elem = expr.elements[-1] | ||
if expr.head == SymbolSequence or ( | ||
not isinstance(expr, ListExpression) | ||
and len == 2 | ||
and isinstance(expr.elements[0], Atom) | ||
): | ||
return last_elem.evaluate(evaluation) | ||
|
||
return expr.elements[-1] | ||
return last_elem | ||
|
||
|
||
class Length(Builtin): | ||
|
@@ -906,17 +979,21 @@ class Most(Builtin): | |
>> Most[a + b + c] | ||
= a + b | ||
>> Most[x] | ||
: Nonatomic expression expected. | ||
: Nonatomic expression expected at position 1 in Most[x]. | ||
= Most[x] | ||
""" | ||
|
||
messages = { | ||
"normal": "Nonatomic expression expected at position 1 in `1`.", | ||
} | ||
|
||
summary_text = "remove the last element" | ||
|
||
def eval(self, expr, evaluation): | ||
def eval(self, expr, evaluation: Evaluation, expression: Expression): | ||
"Most[expr_]" | ||
|
||
if isinstance(expr, Atom): | ||
evaluation.message("Most", "normal") | ||
evaluation.message("Most", "normal", expression) | ||
return | ||
return expr.slice(expr.head, slice(0, -1), evaluation) | ||
|
||
|
@@ -1395,24 +1472,24 @@ class Rest(Builtin): | |
>> Rest[a + b + c] | ||
= b + c | ||
>> Rest[x] | ||
: Nonatomic expression expected. | ||
: Nonatomic expression expected at position 1 in Rest[x]. | ||
= Rest[x] | ||
>> Rest[{}] | ||
: Cannot take Rest of expression {} with length zero. | ||
= Rest[{}] | ||
""" | ||
|
||
messages = { | ||
"normal": "Nonatomic expression expected.", | ||
"normal": "Nonatomic expression expected at position 1 in `1`.", | ||
"norest": "Cannot take Rest of expression `1` with length zero.", | ||
} | ||
summary_text = "remove the first element" | ||
|
||
def eval(self, expr, evaluation): | ||
def eval(self, expr, evaluation: Evaluation, expression: Expression): | ||
"Rest[expr_]" | ||
|
||
if isinstance(expr, Atom): | ||
evaluation.message("Rest", "normal") | ||
evaluation.message("Rest", "normal", expression) | ||
return | ||
if len(expr.elements) == 0: | ||
evaluation.message("Rest", "norest", expr) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First
andLast
should have a default value as second arg and attributeA_HOLD_REST
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@axkr, you are right:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - this should be handled now.