[prettyprint] r578 committed - Make initializations of tuples from strict-prefix literals work...

0 views
Skip to first unread message

prett...@googlecode.com

unread,
Jun 30, 2010, 8:45:28 PM6/30/10
to pp-d...@googlegroups.com
Revision: 578
Author: thockin
Date: Wed Jun 30 17:44:21 2010
Log: Make initializations of tuples from strict-prefix literals work

Make FunctionLiteral more strict about taking params arg

Rename LiteralExpression to ValueExpression


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

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

=======================================
--- /trunk/language/TODO.language Wed Jun 30 08:09:52 2010
+++ /trunk/language/TODO.language Wed Jun 30 17:44:21 2010
@@ -10,6 +10,8 @@
list x = [ 1, 2 ]; // detect x as list<int>
tuple x = [ 1, "2" ]; // detext x as tuple<int, string>

+make func take type args and check them for type safety
+
Can I find a way to name tuple members?

When calling functions is it pass by value or ref? How about assignments?
=======================================
--- /trunk/language/grammar.y Wed Jun 30 08:09:52 2010
+++ /trunk/language/grammar.y Wed Jun 30 17:44:21 2010
@@ -253,12 +253,14 @@
: TOK_FUNC_LITERAL compound_statement {
SYNTRACE("function_literal",
"FUNC_LITERAL compound_statement");
- $$ = new FunctionLiteralExpression(curpos(), $2);
+ $$ = new FunctionLiteralExpression(curpos(),
+ new ParameterDeclarationList(), $2);
}
| TOK_FUNC_LITERAL '(' ')'compound_statement {
SYNTRACE("function_literal",
"FUNC_LITERAL '(' ')' compound_statement");
- $$ = new FunctionLiteralExpression(curpos(), $4);
+ $$ = new FunctionLiteralExpression(curpos(),
+ new ParameterDeclarationList(), $4);
}
| TOK_FUNC_LITERAL '(' parameter_declaration_list ')'
compound_statement {
@@ -1136,7 +1138,7 @@
InitializedIdentifierList *var_list
= new InitializedIdentifierList();
Expression *body = new
- FunctionLiteralExpression(curpos(), $4);
+ FunctionLiteralExpression(curpos(), new ParameterDeclarationList(), $4);
InitializedIdentifier *init_ident
= new InitializedIdentifier(curpos(), $1, body);
var_list->push_back(init_ident);
=======================================
--- /trunk/language/syntax_tree.cpp Wed Jun 30 08:09:52 2010
+++ /trunk/language/syntax_tree.cpp Wed Jun 30 17:44:21 2010
@@ -466,13 +466,13 @@
}

string
-LiteralExpression::to_string() const
+ValueExpression::to_string() const
{
return datum_to_string(m_value.get());
}

void
-LiteralExpression::evaluate(Variable *out_result)
+ValueExpression::evaluate(Variable *out_result)
{
//FIXME:
(void)out_result;
@@ -483,19 +483,15 @@
FunctionLiteralExpression::to_string() const
{
string ret = "$";
- if (m_params) {
- ret += "(";
- for (size_t i = 0; i < m_params->size(); i++) {
- if (i > 0) {
- ret += ", ";
- }
- ret += m_params->at(i)->to_string();
- }
- ret += ")";
- }
- if (m_body) {
- ret += m_body->to_string();
- }
+ ret += "(";
+ for (size_t i = 0; i < m_params->size(); i++) {
+ if (i > 0) {
+ ret += ", ";
+ }
+ ret += m_params->at(i)->to_string();
+ }
+ ret += ")";
+ ret += m_body->to_string();
return ret;
}

=======================================
--- /trunk/language/syntax_tree.h Wed Jun 30 08:09:52 2010
+++ /trunk/language/syntax_tree.h Wed Jun 30 17:44:21 2010
@@ -1226,9 +1226,9 @@
};
typedef std::vector<ParameterDeclaration*> ParameterDeclarationList;

-class LiteralExpression : public Expression {
+class ValueExpression : public Expression {
public:
- LiteralExpression(const Parser::Position &pos, const Variable::Datum
*value)
+ ValueExpression(const Parser::Position &pos, const Variable::Datum *value)
: Expression(pos), m_value(value)
{
// It doesn't make much sense to have a non-const literal.
@@ -1256,45 +1256,39 @@
};

// Helpers for easier usage.
-class BoolLiteralExpression : public LiteralExpression {
+class BoolLiteralExpression : public ValueExpression {
public:
BoolLiteralExpression(const Parser::Position &pos, bool val)
- : LiteralExpression(pos,
- new Variable::Datum(Type(Type::BOOL, Type::CONST), val))
+ : ValueExpression(pos,
+ new Variable::Datum(Type(Type::BOOL, Type::LITERAL), val))
{
}
};
-class IntLiteralExpression : public LiteralExpression {
+class IntLiteralExpression : public ValueExpression {
public:
IntLiteralExpression(const Parser::Position &pos, const Value &val)
- : LiteralExpression(pos,
- new Variable::Datum(Type(Type::INT, Type::CONST), val))
+ : ValueExpression(pos,
+ new Variable::Datum(Type(Type::INT, Type::LITERAL), val))
{
}
};
-class StringLiteralExpression : public LiteralExpression {
+class StringLiteralExpression : public ValueExpression {
public:
StringLiteralExpression(const Parser::Position &pos, const string &val)
- : LiteralExpression(pos,
- new Variable::Datum(Type(Type::STRING, Type::CONST), val))
+ : ValueExpression(pos,
+ new Variable::Datum(Type(Type::STRING, Type::LITERAL), val))
{
}
};

class FunctionLiteralExpression : public Expression {
public:
- FunctionLiteralExpression(const Parser::Position &pos, Statement *body)
- : Expression(pos),
- m_params(NULL), m_body(body)
- {
- set_result_type(Type(Type::FUNC, Type::CONST));
- }
FunctionLiteralExpression(const Parser::Position &pos,
ParameterDeclarationList *params,
Statement *body)
: Expression(pos), m_params(params), m_body(body)
{
- set_result_type(Type(Type::FUNC, Type::CONST));
+ set_result_type(Type(Type::FUNC, Type::LITERAL));
}

Statement *body() const
@@ -1313,10 +1307,8 @@
static DefinitionStatement *args_defn = new_args_definition();
env->add_symbol("args", args_defn);
warnings += m_body->validate_once(flags, env);
- if (m_params) {
- for (size_t i = 0; i < m_params->size(); i++) {
- warnings += m_params->at(i)->validate_once(flags, env);
- }
+ for (size_t i = 0; i < m_params->size(); i++) {
+ warnings += m_params->at(i)->validate_once(flags, env);
}
env->end_symbol_scope();
return warnings;
@@ -1336,7 +1328,7 @@
return new DefinitionStatement(pos, args_type, ident_list);
}

- util::MaybeNullScopedPtr<ParameterDeclarationList> m_params;
+ util::NeverNullScopedPtr<ParameterDeclarationList> m_params;
util::NeverNullScopedPtr<Statement> m_body;
};

@@ -1345,7 +1337,7 @@
TupleLiteralExpression(const Parser::Position &pos, ArgumentList
*contents)
: Expression(pos), m_contents(contents)
{
- set_result_type(Type(Type::TUPLE, Type::CONST));
+ set_result_type(Type(Type::TUPLE, Type::LITERAL));
}

ArgumentList *contents()
=======================================
--- /trunk/language/type.cpp Wed Jun 30 08:09:52 2010
+++ /trunk/language/type.cpp Wed Jun 30 17:44:21 2010
@@ -21,7 +21,7 @@
// Clean up arguments.
m_arguments.clear();
m_primitive = prim;
- m_is_const = false;
+ m_is_const = 0;
return this;
}
Type *
@@ -112,7 +112,7 @@
string
Type::to_string() const
{
- string str = (m_is_const ? "const " : "")
+ string str = (is_const() ? "const " : "")
+ primitive_to_string(m_primitive);
if (primitive_max_args(m_primitive) > 0) {
str += "<";
@@ -132,7 +132,7 @@
bool
Type::is_equal_to(const Type &other) const
{
- if (m_is_const != other.m_is_const) {
+ if (is_const() != other.is_const()) {
return false;
}
if (m_primitive != other.m_primitive) {
@@ -157,7 +157,7 @@
{
if (!ignore_const) {
// Const types are never assignable.
- if (m_is_const) {
+ if (is_const()) {
return false;
}
}
@@ -185,10 +185,20 @@
}
// 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 of the type-args must also be assignable.
- for (size_t i = 0; i < m_arguments.size(); i++) {
+ // Special case: a tuple can be initialized from a literal that is
+ // a strict prefix of the tuple's type.
+ if (m_primitive == TUPLE && other.m_primitive == TUPLE
+ && m_arguments.size() > other.m_arguments.size()
+ && other.is_literal()) {
+ // The code is easier to read this way.
+ } else {
+ return false;
+ }
+ }
+ // This allows the strict prefix init of tuples.
+ size_t n_args = std::min(m_arguments.size(), other.m_arguments.size());
+ // The type-args must also be assignable.
+ 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)) {
=======================================
--- /trunk/language/type.h Thu Jun 24 17:50:36 2010
+++ /trunk/language/type.h Wed Jun 30 17:44:21 2010
@@ -25,13 +25,14 @@
};

// Used for clearer constness management when creating const Types and
- // Variables. You can add CONST as an argument to most of the ctors
+ // Variables. You can add Constness as an argument to most of the ctors
// because it is always safe to add constness to a reference. You can
// not add NON_CONST as a qualifier because it is a logical flub. If
// the Variable or Type is already non-const it is a no-op. If the
// Variable or Type is const it is an error.
enum Constness {
- CONST = 1
+ CONST = 1,
+ LITERAL = 2,
};

// A generic type error. Prefer using subclasses when possible.
@@ -58,7 +59,7 @@

// Implicit conversion is OK.
Type(Primitive prim)
- : m_primitive(prim), m_is_const(false), m_arguments()
+ : m_primitive(prim), m_is_const(0), m_arguments()
{
}
Type(Primitive prim, Constness constness)
@@ -123,15 +124,21 @@
bool
is_const() const
{
- return m_is_const;
+ return m_is_const != 0;
}

Type *
set_const()
{
- m_is_const = true;
+ m_is_const = CONST;
return this;
}
+
+ bool
+ is_literal() const
+ {
+ return m_is_const == LITERAL;
+ }

size_t
n_arguments() const
@@ -164,9 +171,10 @@

Primitive m_primitive;
// In general, constness applies to a Variable, not a Type. In order
- // to make Type arguments easier, we keep a notion of constness here,
- // which we copy into Variables as they are created.
- bool m_is_const;
+ // to make Type arguments and some literal assigments easier, we keep a
+ // notion of constness here, which we can copy into Variables as they are
+ // created.
+ int m_is_const;
std::vector<Type> m_arguments;
};

Reply all
Reply to author
Forward
0 new messages