[vala] Updated genie parser to match vala parser in functionality and bug fixes



commit 73e8e6a6e905342ab92052c0d36ea827fe202d8f
Author: Jamie McCracken <jamiemcc gnome org>
Date:   Tue Apr 14 11:17:42 2009 -0400

    Updated genie parser to match vala parser in functionality and bug fixes
---
 vala/valagenieparser.vala    |  318 ++++++++++++++++++++++++++++++------------
 vala/valageniescanner.vala   |    9 +-
 vala/valagenietokentype.vala |    2 +
 3 files changed, 239 insertions(+), 90 deletions(-)

diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 3bca600..3ef7465 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -61,10 +61,11 @@ public class Vala.Genie.Parser : CodeVisitor {
 		CLASS = 1 << 1,
 		EXTERN = 1 << 2,
 		INLINE = 1 << 3,
-		OVERRIDE = 1 << 4,
-		STATIC = 1 << 5,
-		VIRTUAL = 1 << 6,
-		PRIVATE = 1 << 7
+		NEW = 1 << 4,
+		OVERRIDE = 1 << 5,
+		STATIC = 1 << 6,
+		VIRTUAL = 1 << 7,
+		PRIVATE = 1 << 8
 	}
 
 	public Parser () {
@@ -177,6 +178,10 @@ public class Vala.Genie.Parser : CodeVisitor {
 	inline SourceLocation get_location () {
 		return tokens[index].begin;
 	}
+	
+	string get_current_string () {
+		return ((string) tokens[index].begin.pos).ndup ((tokens[index].end.pos - tokens[index].begin.pos));
+	}
 
 	string get_last_string () {
 		int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
@@ -253,6 +258,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.INIT:
 		case TokenType.INLINE:
 		case TokenType.INTERFACE:
+		case TokenType.INTERNAL:
 		case TokenType.IS:
 		case TokenType.ISA:
 		case TokenType.LOCK:
@@ -262,6 +268,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.OF:
 		case TokenType.OUT:
 		case TokenType.OVERRIDE:
+		case TokenType.OWNED:
 		case TokenType.PASS:
 		case TokenType.PRINT:
 		case TokenType.PRIVATE:
@@ -281,6 +288,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.TRUE:
 		case TokenType.TRY:
 		case TokenType.TYPEOF:
+		case TokenType.UNOWNED:
 		case TokenType.USES:
 		case TokenType.VAR:
 		case TokenType.VIRTUAL:
@@ -289,11 +297,25 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.WEAK:
 		case TokenType.WHEN:
 		case TokenType.WHILE:
+		case TokenType.YIELD:
+		case TokenType.YIELDS:
 			next ();
 			return;
-		default:
-			throw new ParseError.SYNTAX (get_error ("expected identifier"));
-		}
+		case TokenType.INTEGER_LITERAL:
+		case TokenType.REAL_LITERAL:
+			// also accept integer and real literals
+			// as long as they contain at least one character
+			// and no decimal point
+			// for example, 2D and 3D
+			string id = get_current_string ();
+			if (id[id.length - 1].isalpha () && !("." in id)) {
+				next ();
+				return;
+			}
+			break;
+		}	
+
+		throw new ParseError.SYNTAX (get_error ("expected identifier"));
 	}
 
 	string parse_identifier () throws ParseError {
@@ -328,6 +350,11 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.STRING_LITERAL:
 			next ();
 			return new StringLiteral (get_last_string (), get_src (begin));
+		case TokenType.VERBATIM_STRING_LITERAL:
+			next ();
+			string raw_string = get_last_string ();
+			string escaped_string = raw_string.substring (3, raw_string.len () - 6).escape ("");
+			return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));	
 		case TokenType.NULL:
 			next ();
 			return new NullLiteral (get_src (begin));
@@ -392,9 +419,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 			return;
 		}
 		accept (TokenType.DYNAMIC);
-
+		accept (TokenType.OWNED);
+		accept (TokenType.UNOWNED);
 		accept (TokenType.WEAK);
-		
 		if (accept (TokenType.ARRAY) || accept (TokenType.LIST) || accept (TokenType.DICT)) {
 			accept (TokenType.OF);
 		}
@@ -431,7 +458,12 @@ public class Vala.Genie.Parser : CodeVisitor {
 		bool is_dynamic = accept (TokenType.DYNAMIC);
 		bool value_owned = owned_by_default;
 		if (owned_by_default) {
-			value_owned = !accept (TokenType.WEAK);
+			if (accept (TokenType.UNOWNED)
+			    || accept (TokenType.WEAK)) {
+				value_owned = false;
+			}
+		} else {
+			value_owned = accept (TokenType.OWNED);
 		}
 
 		/* handle arrays */
@@ -498,21 +530,34 @@ public class Vala.Genie.Parser : CodeVisitor {
 				prev ();
 			
 				while (accept (TokenType.OPEN_BRACKET))	{		
+					int array_length = -1;
 					int array_rank = 0;
 					do {
 						array_rank++;
 						// support for stack-allocated arrays
 						// also required for decision between expression and declaration statement
 						if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) {
-							parse_expression ();
+							var length_expression = parse_expression ();
+							var length_literal = length_expression as IntegerLiteral;
+							if (length_literal != null) {
+								array_length = length_literal.value.to_int ();
+							}
 						}
 					}
 					while (accept (TokenType.COMMA));
 					expect (TokenType.CLOSE_BRACKET);
 
 					type.value_owned = true;
-					type = new ArrayType (type, array_rank, get_src (begin));
-					type.nullable = accept (TokenType.INTERR);
+					var array_type = new ArrayType (type, array_rank, get_src (begin));
+					array_type.nullable = accept (TokenType.INTERR);
+					
+					if (array_rank == 1 && array_length > 0) {
+						// fixed length (stack-allocated) array
+						array_type.fixed_length = true;
+						array_type.length = array_length;
+					}
+					
+					type = array_type;
 				}
 			}
 		}
@@ -530,11 +575,25 @@ public class Vala.Genie.Parser : CodeVisitor {
 		var list = new ArrayList<Expression> ();
 		if (current () != TokenType.CLOSE_PARENS) {
 			do {
-				list.add (parse_expression ());
+				list.add (parse_argument ());
 			} while (accept (TokenType.COMMA));
 		}
 		return list;
 	}
+	
+	Expression parse_argument () throws ParseError {
+		var begin = get_location ();
+
+		if (accept (TokenType.REF)) {
+			var inner = parse_expression ();
+			return new UnaryExpression (UnaryOperator.REF, inner, get_src (begin));
+		} else if (accept (TokenType.OUT)) {
+			var inner = parse_expression ();
+			return new UnaryExpression (UnaryOperator.OUT, inner, get_src (begin));
+		} else {
+			return parse_expression ();
+		}
+	}
 
 	Expression parse_primary_expression () throws ParseError {
 		var begin = get_location ();
@@ -548,11 +607,15 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.REAL_LITERAL:
 		case TokenType.CHARACTER_LITERAL:
 		case TokenType.STRING_LITERAL:
+		case TokenType.VERBATIM_STRING_LITERAL:
 		case TokenType.NULL:
 			expr = parse_literal ();
 			break;
 		case TokenType.ASSERT:
 			return parse_assert_expression ();	
+		case TokenType.OPEN_BRACE:
+			expr = parse_initializer ();
+			break;
 		case TokenType.OPEN_PARENS:
 			expr = parse_tuple ();
 			break;
@@ -1033,8 +1096,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.TILDE:  return UnaryOperator.BITWISE_COMPLEMENT;
 		case TokenType.OP_INC: return UnaryOperator.INCREMENT;
 		case TokenType.OP_DEC: return UnaryOperator.DECREMENT;
-		case TokenType.REF:    return UnaryOperator.REF;
-		case TokenType.OUT:    return UnaryOperator.OUT;
 		default:               return UnaryOperator.NONE;
 		}
 	}
@@ -1055,9 +1116,16 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.OPEN_PARENS:
 			next ();
 			switch (current ()) {
+			case TokenType.OWNED:
+				// (owned) foo
+				next ();
+				if (accept (TokenType.CLOSE_PARENS)) {
+					var op = parse_unary_expression ();
+					return new ReferenceTransferExpression (op, get_src (begin));
+				}
+				break;
 			case TokenType.VOID:
 			case TokenType.DYNAMIC:
-			case TokenType.WEAK:
 			case TokenType.IDENTIFIER:
 				var type = parse_type ();
 				if (accept (TokenType.CLOSE_PARENS)) {
@@ -1072,6 +1140,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 					case TokenType.REAL_LITERAL:
 					case TokenType.CHARACTER_LITERAL:
 					case TokenType.STRING_LITERAL:
+					case TokenType.VERBATIM_STRING_LITERAL:
 					case TokenType.NULL:
 					case TokenType.THIS:
 					case TokenType.SUPER:
@@ -1079,9 +1148,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 					case TokenType.SIZEOF:
 					case TokenType.TYPEOF:
 					case TokenType.IDENTIFIER:
-						if (!(type is PointerType) && !type.value_owned) {
-							Report.warning (get_src (begin), "obsolete syntax, weak type modifier unused in cast expressions");
-						}
+					case TokenType.PARAMS:
 						var inner = parse_unary_expression ();
 						return new CastExpression (inner, type, get_src (begin), false);
 					default:
@@ -1553,7 +1620,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 					is_decl = true;
 					parse_local_variable_declarations (block);
 					break;
-
+				case TokenType.YIELD:
+					stmt = parse_yield_statement ();
+					break;
 
 				case TokenType.OP_INC:
 				case TokenType.OP_DEC:
@@ -1650,6 +1719,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.BREAK:     return parse_break_statement ();
 		case TokenType.CONTINUE:  return parse_continue_statement ();
 		case TokenType.RETURN:    return parse_return_statement ();
+		case TokenType.YIELD:     return parse_yield_statement ();
 		case TokenType.RAISE:     return parse_throw_statement ();
 		case TokenType.TRY:       return parse_try_statement ();
 		case TokenType.LOCK:      return parse_lock_statement ();
@@ -1670,6 +1740,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 			}
 		}
 
+		block.source_reference.last_line = get_current_src ().last_line;
+		block.source_reference.last_column = get_current_src ().last_column;
+		
 		return block;
 	}
 
@@ -1737,7 +1810,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		var begin = get_location ();
 		Expression initializer = null;
 		if (accept (TokenType.ASSIGN)) {
-			initializer = parse_variable_initializer ();
+			initializer = parse_expression ();
 		}
 		return new LocalVariable (variable_type, id, initializer, get_src_com (begin));
 	}
@@ -2004,6 +2077,17 @@ public class Vala.Genie.Parser : CodeVisitor {
 		return new ReturnStatement (expr, get_src_com (begin));
 	}
 
+	Statement parse_yield_statement () throws ParseError {
+		var begin = get_location ();
+		expect (TokenType.YIELD);
+		Expression expr = null;
+		if (current () != TokenType.SEMICOLON && current () != TokenType.EOL) {
+			expr = parse_expression ();
+		}
+		expect_terminator ();
+		return new YieldStatement (expr, get_src (begin));
+	}
+
 	Statement parse_throw_statement () throws ParseError {
 		var begin = get_location ();
 		expect (TokenType.RAISE);
@@ -2117,6 +2201,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 	Symbol parse_declaration (bool is_root = false) throws ParseError {
 		comment = scanner.pop_comment ();
 		var attrs = parse_attributes ();
+		var begin = get_location ();
 		
 		switch (current ()) {
 		case TokenType.CONST:
@@ -2151,7 +2236,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		case TokenType.STRUCT:	
 			return parse_struct_declaration (attrs);
 		default: 
-			var begin = get_location ();
+			
 			while (current () != TokenType.EOL && current () != TokenType.SEMICOLON && current () != TokenType.EOF) {
 				if (current () == TokenType.COLON) {
 					rollback (begin);
@@ -2241,6 +2326,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 			case TokenType.DELETE:
 			case TokenType.DO:
 			case TokenType.FOR:
+			case TokenType.FOREACH:
 			case TokenType.IF:
 			case TokenType.LOCK:
 			case TokenType.RETURN:
@@ -2248,6 +2334,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 			case TokenType.TRY:
 			case TokenType.VAR:
 			case TokenType.WHILE:
+			case TokenType.YIELD:
 				return RecoveryState.STATEMENT_BEGIN;
 			default:
 				next ();
@@ -2265,7 +2352,15 @@ public class Vala.Genie.Parser : CodeVisitor {
 		set_attributes (ns, attrs);
 		expect (TokenType.EOL);
 		parse_declarations (ns);
-		return ns;
+		
+		Namespace result = ns;
+		while (sym.inner != null) {
+			sym = sym.inner;
+			ns = new Namespace (sym.name, result.source_reference);
+			ns.add_namespace ((Namespace) result);
+			result = ns;
+		}
+		return result;
 	}
 
 	void parse_namespace_member (Namespace ns) throws ParseError {
@@ -2392,7 +2487,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 		    && !cl.is_abstract
 		    && cl.default_construction_method == null) {
 			var m = new CreationMethod (cl.name, null, cl.source_reference);
-			m.binding = MemberBinding.STATIC;
 			m.access = SymbolAccessibility.PUBLIC;
 			m.body = new Block (cl.source_reference);
 			cl.add_method (m);
@@ -2443,7 +2537,14 @@ public class Vala.Genie.Parser : CodeVisitor {
 			 	cl.static_constructor = c;
 			 }
 		} else if (sym is Destructor) {
-			cl.destructor = (Destructor) sym;
+			var d = (Destructor) sym;
+			if (d.binding == MemberBinding.STATIC) {
+				cl.static_destructor = (Destructor) d;
+			} else if (d.binding == MemberBinding.CLASS) {
+				cl.class_destructor = (Destructor) d;
+			} else {
+				cl.destructor = (Destructor) d;
+			}
 		} else {
 			Report.error (sym.source_reference, "unexpected declaration in class");
 		}
@@ -2454,7 +2555,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		expect (TokenType.CONST);
 
-		parse_member_declaration_modifiers ();
+		var flags = parse_member_declaration_modifiers ();
 
 		string id = parse_identifier ();
 		expect (TokenType.COLON);
@@ -2462,7 +2563,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		Expression initializer = null;
 		if (accept (TokenType.ASSIGN)) {
-			initializer = parse_variable_initializer ();
+			initializer = parse_expression ();
 		}
 		expect_terminator ();
 
@@ -2474,6 +2575,14 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		var c = new Constant (id, type, initializer, get_src_com (begin));
 		c.access = get_access (id);
+		
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			c.external = true;
+		}
+		if (ModifierFlags.NEW in flags) {
+			c.hides = true;
+		}
+		
 		set_attributes (c, attrs);
 		return c;
 	}
@@ -2501,6 +2610,13 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		set_attributes (f, attrs);
 
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			f.external = true;
+		}
+		if (ModifierFlags.NEW in flags) {
+			f.hides = true;
+		}
+
 		if (accept (TokenType.ASSIGN)) {
 			f.initializer = parse_expression ();
 		}
@@ -2524,7 +2640,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		var initializer = new InitializerList (get_src (begin));
 		if (current () != TokenType.DEDENT) {
 			do {
-				var init = parse_variable_initializer ();
+				var init = parse_argument ();
 				initializer.append (init);
 			} while (accept (TokenType.COMMA));
 		}
@@ -2534,41 +2650,8 @@ public class Vala.Genie.Parser : CodeVisitor {
 		return initializer;
 	}
 	
-	bool is_initializer () throws ParseError { 
-		if (current () == TokenType.OPEN_BRACE) {
-			return true;
-		}
-		
-		/*
-		if (current () == TokenType.OPEN_PARENS) {
-			var begin = get_location ();
-			var is_array = false;
-						
-			next ();
-						
-			var expr = parse_expression ();
-			is_array = (accept (TokenType.COMMA));
-			
-			rollback (begin);
-			
-			return is_array;
-		}
-		*/
-		
-		return false;
-	}
 	
-
-	Expression parse_variable_initializer () throws ParseError {
-		if (is_initializer ()) {
-			var expr = parse_initializer ();
-			return expr;
-		} else {
-			var expr = parse_expression ();
-			return expr;
-		}
-	}
-
+	
 
 	Method parse_main_method_declaration (Gee.List<Attribute>? attrs) throws ParseError {
 		var id = "main";
@@ -2644,6 +2727,10 @@ public class Vala.Genie.Parser : CodeVisitor {
 			method.add_parameter (param);
 		}
 
+		if (accept (TokenType.YIELDS)) {
+			method.coroutine = true;
+		}
+
 		if (accept (TokenType.RAISES)) {
 			do {
 				method.add_error_type (parse_type ());
@@ -2653,24 +2740,42 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		if (ModifierFlags.STATIC in flags || id == "main") {
 			method.binding = MemberBinding.STATIC;
+		} else if (ModifierFlags.CLASS in flags) {
+			method.binding = MemberBinding.CLASS;
 		}
-		if (ModifierFlags.ABSTRACT in flags) {
-			method.is_abstract = true;
-		}
-		if (ModifierFlags.VIRTUAL in flags) {
-			method.is_virtual = true;
-		}
-		if (ModifierFlags.OVERRIDE in flags) {
-			method.overrides = true;
+		if (ModifierFlags.NEW in flags) {
+			method.hides = true;
 		}
-		if ((method.is_abstract && method.is_virtual)
-		    || (method.is_abstract && method.overrides)
-		    || (method.is_virtual && method.overrides)) {
-			throw new ParseError.SYNTAX (get_error ("only one of `abstract', `virtual', or `override' may be specified"));
+
+		if (method.binding == MemberBinding.INSTANCE) {
+			if (ModifierFlags.ABSTRACT in flags) {
+				method.is_abstract = true;
+			}
+			if (ModifierFlags.VIRTUAL in flags) {
+				method.is_virtual = true;
+			}
+			if (ModifierFlags.OVERRIDE in flags) {
+				method.overrides = true;
+			}
+			if ((method.is_abstract && method.is_virtual)
+			    || (method.is_abstract && method.overrides)
+			    || (method.is_virtual && method.overrides)) {
+				throw new ParseError.SYNTAX (get_error ("only one of `abstract', `virtual', or `override' may be specified"));
+			}
+		} else {
+			if (ModifierFlags.ABSTRACT in flags
+			    || ModifierFlags.VIRTUAL in flags
+			    || ModifierFlags.OVERRIDE in flags) {
+				throw new ParseError.SYNTAX (get_error ("the modifiers `abstract', `virtual', and `override' are not valid for static methods"));
+			}
 		}
+
 		if (ModifierFlags.INLINE in flags) {
 			method.is_inline = true;
 		}
+		if (ModifierFlags.EXTERN in flags) {
+			method.external = true;
+		}
 
 		expect (TokenType.EOL);
 
@@ -2719,6 +2824,8 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		if (accept_block ()) {
 			method.body = parse_block ();
+		} else if (scanner.source_file.external_package) {
+			method.external = true;
 		}
 		return method;
 	}
@@ -2736,7 +2843,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 		string id = parse_identifier ();
 		expect (TokenType.COLON);
 
-		bool is_weak = accept (TokenType.WEAK);
 		var type = parse_type (false);
 
 		var prop = new Property (id, type, null, null, get_src_com (begin));
@@ -2762,6 +2868,13 @@ public class Vala.Genie.Parser : CodeVisitor {
 		if (ModifierFlags.OVERRIDE in flags) {
 			prop.overrides = true;
 		}
+		
+		if (ModifierFlags.NEW in flags) {
+			prop.hides = true;
+		}
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			prop.external = true;
+		}
 
 		if (accept (TokenType.ASSIGN)) {
 			prop.default_expression = parse_expression ();
@@ -2775,7 +2888,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 				var attribs = parse_attributes ();
 
 				var value_type = type.copy ();
-				value_type.value_owned = false;
+				value_type.value_owned = accept (TokenType.OWNED);
 
 				if (accept (TokenType.GET)) {
 					if (prop.get_accessor != null) {
@@ -2784,8 +2897,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 					Block block = null;
 					if (accept_block ()) {
 						block = parse_block ();
+						prop.external = false;
 					}
-					prop.get_accessor = new PropertyAccessor (true, false, false, type.copy (), block, get_src (accessor_begin));
+					prop.get_accessor = new PropertyAccessor (true, false, false, value_type, block, get_src (accessor_begin));
 					set_attributes (prop.get_accessor, attribs);
 					prop.get_accessor.access = SymbolAccessibility.PUBLIC;
 				} else {
@@ -2808,6 +2922,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 					Block block = null;
 					if (accept_block ()) {
 						block = parse_block ();
+						prop.external = false;
 					}
 					prop.set_accessor = new PropertyAccessor (false, !readonly, _construct, value_type, block, get_src (accessor_begin));
 					set_attributes (prop.set_accessor, attribs);
@@ -2845,7 +2960,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 			if (needs_var) {
 				/* automatic property accessor body generation */
 				var field_type = prop.property_type.copy ();
-				field_type.value_owned = !is_weak;
 				prop.field = new Field ("_%s".printf (prop.name), field_type, prop.default_expression, prop.source_reference);
 				prop.field.access = SymbolAccessibility.PRIVATE;
 			}
@@ -2890,7 +3004,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 		if (ModifierFlags.VIRTUAL in flags) {
 			sig.is_virtual = true;
 		}
-
+		if (ModifierFlags.NEW in flags) {
+			sig.hides = true;
+		}
 		set_attributes (sig, attrs);
 		
 		foreach (FormalParameter formal_param in params) {
@@ -3005,7 +3121,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 		} else {
 			iface.access = get_access (sym.name);
 		}
-		
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			iface.external = true;
+		}
 		set_attributes (iface, attrs);
 		foreach (TypeParameter type_param in type_param_list) {
 			iface.add_type_parameter (type_param);
@@ -3070,6 +3188,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 		} else {
 			en.access = get_access (sym.name);
 		}
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			en.external = true;
+		}
 		set_attributes (en, attrs);
 
 		expect (TokenType.EOL);
@@ -3215,6 +3336,10 @@ public class Vala.Genie.Parser : CodeVisitor {
 				next ();
 				flags |= ModifierFlags.INLINE;
 				break;
+			case TokenType.NEW:
+				next ();
+				flags |= ModifierFlags.NEW;
+				break;	
 			case TokenType.OVERRIDE:
 				next ();
 				flags |= ModifierFlags.OVERRIDE;
@@ -3244,7 +3369,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 			// varargs
 			return new FormalParameter.with_ellipsis (get_src (begin));
 		}
-
+		bool params_array = accept (TokenType.PARAMS);
 		var direction = ParameterDirection.IN;
 		if (accept (TokenType.OUT)) {
 			direction = ParameterDirection.OUT;
@@ -3266,6 +3391,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 		var param = new FormalParameter (id, type, get_src (begin));
 		set_attributes (param, attrs);
 		param.direction = direction;
+		param.params_array = params_array;
 		if (accept (TokenType.ASSIGN)) {
 			param.default_expression = parse_expression ();
 		}
@@ -3277,7 +3403,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 		CreationMethod method;
 
 		expect (TokenType.CONSTRUCT);
-
 		parse_member_declaration_modifiers ();
 
 
@@ -3307,6 +3432,9 @@ public class Vala.Genie.Parser : CodeVisitor {
 			} while (accept (TokenType.COMMA));
 		}
 		expect (TokenType.CLOSE_PARENS);
+		if (accept (TokenType.YIELDS)) {
+			method.coroutine = true;
+		}
 		if (accept (TokenType.RAISES)) {
 			do {
 				method.add_error_type (parse_type ());
@@ -3318,6 +3446,8 @@ public class Vala.Genie.Parser : CodeVisitor {
 
 		if (accept_block ()) {
 			method.body = parse_block ();
+		} else if (scanner.source_file.external_package) {
+			method.external = true;
 		}
 		
 		return method;
@@ -3334,7 +3464,10 @@ public class Vala.Genie.Parser : CodeVisitor {
 		var sym = parse_symbol_name ();
 
 		var type_param_list = parse_type_parameter_list ();
-
+		
+		if (ModifierFlags.NEW in flags) {
+			throw new ParseError.SYNTAX (get_error ("`new' modifier not allowed on delegates"));
+		}
 
 		var params = new ArrayList<FormalParameter> ();
 
@@ -3354,21 +3487,30 @@ public class Vala.Genie.Parser : CodeVisitor {
 			type = new VoidType ();
 		}
 
+		var d = new Delegate (sym.name, type, get_src_com (begin));
+
 		if (accept (TokenType.RAISES)) {
 			do {
-				parse_type ();
+				d.add_error_type (parse_type ());
 			} while (accept (TokenType.COMMA));
 		}
 
 		expect_terminator ();
 
-		var d = new Delegate (sym.name, type, get_src_com (begin));
+		
 		if (ModifierFlags.PRIVATE in flags) {
 			d.access = SymbolAccessibility.PRIVATE;
 		} else {
 			d.access = get_access (sym.name);
 		}
 
+		if (!(ModifierFlags.STATIC in flags)) {
+			d.has_target = true;
+		}
+		if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
+			d.external = true;
+		}
+
 		set_attributes (d, attrs);
 
 		foreach (TypeParameter type_param in type_param_list) {
@@ -3379,9 +3521,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 			d.add_parameter (formal_param);
 		}
 
-		if (!(ModifierFlags.STATIC in flags)) {
-			d.has_target = true;
-		}
 
 
 		Symbol result = d;
@@ -3430,6 +3569,7 @@ public class Vala.Genie.Parser : CodeVisitor {
 				switch (current ()) {
 				case TokenType.VOID:
 				case TokenType.DYNAMIC:
+				case TokenType.UNOWNED:
 				case TokenType.WEAK:
 				case TokenType.IDENTIFIER:
 					var type = parse_type ();
diff --git a/vala/valageniescanner.vala b/vala/valageniescanner.vala
index bf31565..d28ff76 100644
--- a/vala/valageniescanner.vala
+++ b/vala/valageniescanner.vala
@@ -307,7 +307,14 @@ public class Vala.Genie.Scanner {
 				if (matches (begin, "inline")) return TokenType.INLINE;
 				break;
 			case 'p':
-				if (matches (begin, "public")) return TokenType.PUBLIC;
+				switch (begin[1]) {
+				case 'a':
+					if (matches (begin, "params")) return TokenType.PARAMS;
+					break;
+				case 'u':
+					if (matches (begin, "public")) return TokenType.PUBLIC;
+					break;
+				}
 				break;
 			case 'r':
 				switch (begin[1]) {
diff --git a/vala/valagenietokentype.vala b/vala/valagenietokentype.vala
index 5193c61..7009029 100644
--- a/vala/valagenietokentype.vala
+++ b/vala/valagenietokentype.vala
@@ -122,6 +122,7 @@ public enum Vala.Genie.TokenType {
 	OPEN_PARENS,
 	OVERRIDE,
 	OWNED,
+	PARAMS,
 	PASS,
 	PERCENT,
 	PLUS,
@@ -264,6 +265,7 @@ public enum Vala.Genie.TokenType {
 		case OPEN_PARENS: return "`('";
 		case OVERRIDE: return "`override'";
 		case OWNED: return "`owned'";
+		case PARAMS: return "`params'";
 		case PASS: return "`pass'";
 		case PERCENT: return "`%'";
 		case PLUS: return "`+'";



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]