[prettyprint] r577 committed - Change list literals to tuple literals....

0 views
Skip to first unread message

prett...@googlecode.com

unread,
Jun 30, 2010, 11:10:43 AM6/30/10
to pp-d...@googlegroups.com
Revision: 577
Author: thockin
Date: Wed Jun 30 08:09:52 2010
Log: Change list literals to tuple literals.

Allow list = tuple if args match.


http://code.google.com/p/prettyprint/source/detail?r=577

Modified:
/trunk/language/TODO.language
/trunk/language/grammar.y
/trunk/language/syntax_tree.cpp
/trunk/language/syntax_tree.h
/trunk/language/tests/type_test.cpp
/trunk/language/type.cpp

=======================================
--- /trunk/language/TODO.language Thu Jun 24 17:50:36 2010
+++ /trunk/language/TODO.language Wed Jun 30 08:09:52 2010
@@ -5,18 +5,11 @@

Define how to convert non-strings to strings, including formatting (hex,
etc)

-Tuple literals?
-
-auto x = [ 1, 2 ]; // detect x as list<int>
-list<auto> x = [ 1, 2 ]; // detect x as list<int>
+tuple<int, bool> = [0] should probably work
+
list x = [ 1, 2 ]; // detect x as list<int>
-tuple<auto, auto> x = [ 1, "2" ]; // detext x as tuple<int, string>
tuple x = [ 1, "2" ]; // detext x as tuple<int, string>

-typedef
-
-struct
-
Can I find a way to name tuple members?

When calling functions is it pass by value or ref? How about assignments?
@@ -26,3 +19,7 @@
Can a file have more than 1 'module' line?

Can a file have 0 'module' lines?
+
+typedef
+
+struct and struct literals
=======================================
--- /trunk/language/grammar.y Thu Jun 24 07:46:16 2010
+++ /trunk/language/grammar.y Wed Jun 30 08:09:52 2010
@@ -114,7 +114,7 @@
multiplicative_expression additive_expression
unary_expression postfix_expression
subscript_expression function_call_expression
- function_literal list_literal
+ function_literal tuple_literal
expression_or_nothing
%type <unary_op> unary_operator
%type <binary_op> assignment_operator
@@ -212,8 +212,8 @@
$$ = new StringLiteralExpression(curpos(), *$1);
delete $1;
}
- | list_literal {
- SYNTRACE("primary_expression", "list_literal");
+ | tuple_literal {
+ SYNTRACE("primary_expression", "tuple_literal");
$$ = $1;
}
| function_literal {
@@ -238,14 +238,14 @@
}
;

-list_literal
+tuple_literal
: '[' ']' {
- SYNTRACE("list_literal", "'[' ']'");
- $$ = new ListLiteralExpression(curpos(), new ArgumentList());
+ SYNTRACE("tuple_literal", "'[' ']'");
+ $$ = new TupleLiteralExpression(curpos(), new ArgumentList());
}
| '[' argument_list ']' {
- SYNTRACE("list_literal", "'[' argument_list ']'");
- $$ = new ListLiteralExpression(curpos(), $2);
+ SYNTRACE("tuple_literal", "'[' argument_list ']'");
+ $$ = new TupleLiteralExpression(curpos(), $2);
}
;

=======================================
--- /trunk/language/syntax_tree.cpp Thu Jun 24 07:46:16 2010
+++ /trunk/language/syntax_tree.cpp Wed Jun 30 08:09:52 2010
@@ -506,7 +506,7 @@
}

string
-ListLiteralExpression::to_string() const
+TupleLiteralExpression::to_string() const
{
string ret = "[";
if (m_contents) {
@@ -522,7 +522,7 @@
}

void
-ListLiteralExpression::evaluate(Variable *out_result)
+TupleLiteralExpression::evaluate(Variable *out_result)
{
(void)out_result;//FIXME:
}
=======================================
--- /trunk/language/syntax_tree.h Thu Jun 24 17:50:36 2010
+++ /trunk/language/syntax_tree.h Wed Jun 30 08:09:52 2010
@@ -1340,12 +1340,12 @@
util::NeverNullScopedPtr<Statement> m_body;
};

-class ListLiteralExpression : public Expression {
+class TupleLiteralExpression : public Expression {
public:
- ListLiteralExpression(const Parser::Position &pos, ArgumentList *contents)
+ TupleLiteralExpression(const Parser::Position &pos, ArgumentList
*contents)
: Expression(pos), m_contents(contents)
{
- set_result_type(Type(Type::LIST, Type::CONST));
+ set_result_type(Type(Type::TUPLE, Type::CONST));
}

ArgumentList *contents()
@@ -1364,25 +1364,14 @@
warnings += m_contents->at(i)->validate_once(flags, env);
}

- // Figure out the actual type of this list literal.
- Type content_type(Type::VAR);
+ // Figure out the type-args of this tuple literal.
+ Type my_result_type = result_type();
for (size_t i = 0; i < m_contents->size(); i++) {
const Argument *arg = m_contents->at(i);
const Type &t = arg->expression()->result_type();
- if (content_type == Type::VAR) {
- content_type = t;
- } else if (t != content_type) {
- content_type = Type::VAR;
- break;
- }
- }
- Type full_result_type = result_type();
- if (content_type != Type::VAR) {
- full_result_type.add_argument(content_type);
- } else {
- full_result_type.add_argument(Type::VAR);
- }
- set_result_type(full_result_type);
+ my_result_type.add_argument(t);
+ }
+ set_result_type(my_result_type);

return warnings;
}
=======================================
--- /trunk/language/tests/type_test.cpp Thu Jun 24 17:50:36 2010
+++ /trunk/language/tests/type_test.cpp Wed Jun 30 08:09:52 2010
@@ -130,6 +130,82 @@
TEST_ASSERT(t1.is_assignable_from(t2));
TEST_ASSERT(t2.is_assignable_from(t1));
}
+ // list<int> = tuple<int>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::INT);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
+ // list<int> = tuple<int, int>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::INT);
+ t2.add_argument(Type::INT);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
+ // list<int> = tuple<var, int>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::VAR);
+ t2.add_argument(Type::INT);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
+ // list<var> = tuple<int, bool>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::VAR);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::INT);
+ t2.add_argument(Type::BOOL);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
+ // list<int> = tuple<bool>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::BOOL);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(!t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
+ // list<int> = tuple<int, bool>
+ {
+ Type t1(Type::LIST);
+ t1.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::INT);
+ t2.add_argument(Type::BOOL);
+
+ TEST_ASSERT(!t1.is_equal_to(t2));
+ TEST_ASSERT(!t1.is_assignable_from(t2));
+ TEST_ASSERT(!t2.is_assignable_from(t1));
+ }
// list<list<int>> = list<list<int>>
{
Type t1(Type::LIST);
@@ -195,18 +271,6 @@
TEST_ASSERT(t1.is_assignable_from(t2));
TEST_ASSERT(t2.is_assignable_from(t1));
}
- // tuple<int> = list<int>
- {
- Type t1(Type::TUPLE);
- t1.add_argument(Type::INT);
-
- Type t2(Type::LIST);
- t2.add_argument(Type::INT);
-
- TEST_ASSERT(!t1.is_equal_to(t2));
- TEST_ASSERT(t1.is_assignable_from(t2));
- TEST_ASSERT(!t2.is_assignable_from(t1));
- }
// tuple<int,int> = tuple<int,int>
{
Type t1(Type::TUPLE);
@@ -221,43 +285,43 @@
TEST_ASSERT(t1.is_assignable_from(t2));
TEST_ASSERT(t2.is_assignable_from(t1));
}
- // tuple<int,int> = list<int,int>
+ // tuple<int> = tuple<bool>
{
Type t1(Type::TUPLE);
t1.add_argument(Type::INT);
- t1.add_argument(Type::INT);
-
- Type t2(Type::LIST);
- t2.add_argument(Type::INT);
+
+ Type t2(Type::TUPLE);
+ t2.add_argument(Type::BOOL);

TEST_ASSERT(!t1.is_equal_to(t2));
- TEST_ASSERT(t1.is_assignable_from(t2));
+ TEST_ASSERT(!t1.is_assignable_from(t2));
TEST_ASSERT(!t2.is_assignable_from(t1));
}
- // tuple<int> = tuple<bool>
+ // tuple<int,int> = tuple<int,bool>
{
Type t1(Type::TUPLE);
t1.add_argument(Type::INT);
+ t1.add_argument(Type::INT);

Type t2(Type::TUPLE);
+ t2.add_argument(Type::INT);
t2.add_argument(Type::BOOL);

TEST_ASSERT(!t1.is_equal_to(t2));
TEST_ASSERT(!t1.is_assignable_from(t2));
TEST_ASSERT(!t2.is_assignable_from(t1));
}
- // tuple<int,int> = tuple<int,bool>
+ // tuple<int,bool> = tuple<int>
{
Type t1(Type::TUPLE);
t1.add_argument(Type::INT);
- t1.add_argument(Type::INT);
+ t1.add_argument(Type::BOOL);

Type t2(Type::TUPLE);
t2.add_argument(Type::INT);
- t2.add_argument(Type::BOOL);

TEST_ASSERT(!t1.is_equal_to(t2));
- TEST_ASSERT(!t1.is_assignable_from(t2));
+ TEST_ASSERT(t1.is_assignable_from(t2));
TEST_ASSERT(!t2.is_assignable_from(t1));
}
// tuple<var> = tuple<bool>
=======================================
--- /trunk/language/type.cpp Thu Jun 24 17:50:36 2010
+++ /trunk/language/type.cpp Wed Jun 30 08:09:52 2010
@@ -166,27 +166,34 @@
if (m_primitive == VAR || other.m_primitive == VAR) {
return true;
}
- // Special case: tuple is assignable from list, as long as args match.
+ // Special case: list is assignable from tuple, as long as args match.
// Otherwise, we apply some other rules.
- if (m_primitive == TUPLE && other.m_primitive == LIST) {
- // The logic is easier to read this way.
+ if (m_primitive == LIST && other.m_primitive == TUPLE) {
+ // We can only assign list = tuple if the list type-arg is assignable
+ // from all of the tuple type-args.
+ const Type &lhs = m_arguments[0];
+ for (size_t i = 0; i < other.m_arguments.size(); i++) {
+ const Type &rhs = other.m_arguments[i];
+ if (!lhs.is_assignable_from(rhs, ignore_const)) {
+ return false;
+ }
+ }
} else {
// If the primitives don't match, it can't be assignable.
if (m_primitive != other.m_primitive) {
return false;
}
- // If the number of arguments don't match, it can't be assignable.
+ // If the number of type-args don't match, it can't be assignable.
if (m_arguments.size() != other.m_arguments.size()) {
return false;
}
- }
- // All arguments must also be assignable.
- size_t n_args = std::min(m_arguments.size(), other.m_arguments.size());
- for (size_t i = 0; i < n_args; i++) {
- const Type &lhs = m_arguments[i];
- const Type &rhs = other.m_arguments[i];
- if (!lhs.is_assignable_from(rhs, ignore_const)) {
- return false;
+ // All of the type-args must also be assignable.
+ for (size_t i = 0; i < m_arguments.size(); i++) {
+ const Type &lhs = m_arguments[i];
+ const Type &rhs = other.m_arguments[i];
+ if (!lhs.is_assignable_from(rhs, ignore_const)) {
+ return false;
+ }
}
}
return true;
@@ -201,7 +208,7 @@
Type::sanity_check() const
{
// Type::add_argument checks that a type does not end up with too many
- // arguments before adding them. We need to check that it got enough.
+ // type-args before adding them. We need to check that it got enough.
switch (m_primitive) {
case BOOL:
case FLDFMT:

Reply all
Reply to author
Forward
0 new messages