[vala] Genie: Briought Genie up to date with Vala
- From: Jamie McCracken <jamiemcc src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Genie: Briought Genie up to date with Vala
- Date: Sun, 27 Sep 2009 15:43:30 +0000 (UTC)
commit e53b00f5a50f6b287e8be2e4dbf8a7b997a43ab0
Author: Jamie McCracken <jamiemcc gnome org>
Date: Sun Sep 27 11:42:47 2009 -0400
Genie: Briought Genie up to date with Vala
Added Async support
Added bug fixes
Added improved warnings
Added improved array handling code
Added support for constants in interfaces
vala/valagenieparser.vala | 155 +++++++++++++++++++++++++++++++-----------
vala/valageniescanner.vala | 43 +++++++++---
vala/valagenietokentype.vala | 6 +-
3 files changed, 150 insertions(+), 54 deletions(-)
---
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 9aa9652..0741593 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -65,7 +65,8 @@ public class Vala.Genie.Parser : CodeVisitor {
OVERRIDE = 1 << 5,
STATIC = 1 << 6,
VIRTUAL = 1 << 7,
- PRIVATE = 1 << 8
+ PRIVATE = 1 << 8,
+ ASYNC = 1 << 9
}
public Parser () {
@@ -218,6 +219,7 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.ABSTRACT:
case TokenType.AS:
case TokenType.ASSERT:
+ case TokenType.ASYNC:
case TokenType.BREAK:
case TokenType.CLASS:
case TokenType.CONST:
@@ -290,7 +292,6 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.WHEN:
case TokenType.WHILE:
case TokenType.YIELD:
- case TokenType.YIELDS:
next ();
return;
case TokenType.INTEGER_LITERAL:
@@ -379,7 +380,7 @@ public class Vala.Genie.Parser : CodeVisitor {
}
}
- parse_using_directives ();
+ parse_using_directives (context.root);
parse_declarations (context.root, true);
} catch (ParseError e) {
// already reported
@@ -522,18 +523,15 @@ public class Vala.Genie.Parser : CodeVisitor {
prev ();
while (accept (TokenType.OPEN_BRACKET)) {
- int array_length = -1;
+ bool invalid_array = false;
int array_rank = 0;
do {
array_rank++;
- // support for stack-allocated arrays
- // also required for decision between expression and declaration statement
+ // required for decision between expression and declaration statement
if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) {
- var length_expression = parse_expression ();
- var length_literal = length_expression as IntegerLiteral;
- if (length_literal != null) {
- array_length = length_literal.value.to_int ();
- }
+ parse_expression ();
+ // only used for parsing, reject use as real type
+ invalid_array = true;
}
}
while (accept (TokenType.COMMA));
@@ -543,11 +541,7 @@ public class Vala.Genie.Parser : CodeVisitor {
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;
- }
+ array_type.invalid_syntax = invalid_array;
type = array_type;
}
@@ -563,6 +557,36 @@ public class Vala.Genie.Parser : CodeVisitor {
return type;
}
+ DataType? parse_inline_array_type (DataType? type) throws ParseError {
+ var begin = get_location ();
+
+ // inline-allocated array
+ if (type != null && accept (TokenType.OPEN_BRACKET)) {
+ int array_length = -1;
+
+ if (current () != TokenType.CLOSE_BRACKET) {
+ if (current () != TokenType.INTEGER_LITERAL) {
+ throw new ParseError.SYNTAX (get_error ("expected `]' or integer literal"));
+ }
+
+ var length_literal = (IntegerLiteral) parse_literal ();
+ array_length = length_literal.value.to_int ();
+ }
+ expect (TokenType.CLOSE_BRACKET);
+
+ var array_type = new ArrayType (type, 1, get_src (begin));
+ array_type.inline_allocated = true;
+ if (array_length > 0) {
+ array_type.fixed_length = true;
+ array_type.length = array_length;
+ }
+
+ return array_type;
+ }
+ return type;
+ }
+
+
Gee.List<Expression> parse_argument_list () throws ParseError {
var list = new ArrayList<Expression> ();
if (current () != TokenType.CLOSE_PARENS) {
@@ -628,6 +652,9 @@ public class Vala.Genie.Parser : CodeVisitor {
case TokenType.TYPEOF:
expr = parse_typeof_expression ();
break;
+ case TokenType.YIELD:
+ expr = parse_yield_expression ();
+ break;
default:
expr = parse_simple_name ();
break;
@@ -1059,6 +1086,15 @@ public class Vala.Genie.Parser : CodeVisitor {
return new MemberInitializer (id, expr, get_src (begin));
}
+ Expression parse_yield_expression () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.YIELD);
+ var member = parse_member_name ();
+ var call = (MethodCall) parse_method_call (begin, member);
+ call.is_yield_expression = true;
+ return call;
+ }
+
Expression parse_sizeof_expression () throws ParseError {
var begin = get_location ();
expect (TokenType.SIZEOF);
@@ -1784,11 +1820,12 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.COLON);
variable_type = parse_type ();
+ var type = parse_inline_array_type (variable_type);
foreach (string id in id_list) {
DataType type_copy = null;
- if (variable_type != null) {
- type_copy = variable_type.copy ();
+ if (type != null) {
+ type_copy = type.copy ();
}
var local = parse_local_variable (type_copy, id);
block.add_statement (new DeclarationStatement (local, local.source_reference));
@@ -2065,14 +2102,18 @@ public class Vala.Genie.Parser : CodeVisitor {
expr = parse_expression ();
}
expect_terminator ();
- return new ReturnStatement (expr, get_src (begin));
+ return new ReturnStatement (expr, get_src (begin));
}
Statement parse_yield_statement () throws ParseError {
var begin = get_location ();
expect (TokenType.YIELD);
+ if (current () != TokenType.SEMICOLON && current () != TokenType.EOL && current () != TokenType.RETURN) {
+ prev ();
+ return parse_expression_statement ();
+ }
Expression expr = null;
- if (current () != TokenType.SEMICOLON && current () != TokenType.EOL) {
+ if (accept (TokenType.RETURN)) {
expr = parse_expression ();
}
expect_terminator ();
@@ -2205,7 +2246,11 @@ public class Vala.Genie.Parser : CodeVisitor {
if (is_root) {
return parse_main_method_declaration (attrs);
}
- return parse_constructor_declaration (attrs);
+ if (context.profile == Profile.GOBJECT) {
+ rollback (begin);
+ return parse_constructor_declaration (attrs);
+ }
+ break;
case TokenType.DELEGATE:
return parse_delegate_declaration (attrs);
case TokenType.DEF:
@@ -2396,29 +2441,29 @@ public class Vala.Genie.Parser : CodeVisitor {
}
- void add_uses_clause () throws ParseError {
+ void add_uses_clause (Namespace ns) throws ParseError {
var begin = get_location ();
var sym = parse_symbol_name ();
var ns_ref = new UsingDirective (sym, get_src (begin));
-
+
scanner.source_file.add_using_directive (ns_ref);
- context.root.add_using_directive (ns_ref);
+ ns.add_using_directive (ns_ref);
}
- void parse_using_directives () throws ParseError {
+ void parse_using_directives (Namespace ns) throws ParseError {
while (accept (TokenType.USES)) {
if (accept_block ()) {
expect (TokenType.INDENT);
while (current () != TokenType.DEDENT && current () != TokenType.EOF) {
- add_uses_clause ();
+ add_uses_clause (ns);
expect (TokenType.EOL);
}
expect (TokenType.DEDENT);
} else {
do {
- add_uses_clause ();
+ add_uses_clause (ns);
} while (accept (TokenType.COMMA));
expect_terminator ();
@@ -2480,7 +2525,6 @@ public class Vala.Genie.Parser : CodeVisitor {
// ensure there is always a default construction method
if (!scanner.source_file.external_package
- && !cl.is_abstract
&& cl.default_construction_method == null) {
var m = new CreationMethod (cl.name, null, cl.source_reference);
m.access = SymbolAccessibility.PUBLIC;
@@ -2554,8 +2598,10 @@ public class Vala.Genie.Parser : CodeVisitor {
var flags = parse_member_declaration_modifiers ();
string id = parse_identifier ();
+
expect (TokenType.COLON);
var type = parse_type (false);
+ type = parse_inline_array_type (type);
Expression initializer = null;
if (accept (TokenType.ASSIGN)) {
@@ -2591,8 +2637,10 @@ public class Vala.Genie.Parser : CodeVisitor {
var flags = parse_member_declaration_modifiers ();
var type = parse_type ();
+
+ type = parse_inline_array_type (type);
- var f = new Field (id, type, null, get_src (begin), comment);
+ var f = new Field (id, type, null, get_src (begin), comment);
if (ModifierFlags.ABSTRACT in flags || ModifierFlags.VIRTUAL in flags || ModifierFlags.OVERRIDE in flags) {
Report.error (f.source_reference, "abstract, virtual, and override modifiers are not applicable to fields");
@@ -2701,13 +2749,15 @@ public class Vala.Genie.Parser : CodeVisitor {
expect (TokenType.CLOSE_PARENS);
+
/* deal with return value */
if (accept (TokenType.COLON)) {
type = parse_type ();
- parse_type_parameter_list ();
}
+
+ var type_param_list = parse_type_parameter_list ();
- var method = new Method (id, type, get_src (begin), comment);
+ var method = new Method (id, type, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
method.access = SymbolAccessibility.PRIVATE;
} else {
@@ -2717,12 +2767,13 @@ public class Vala.Genie.Parser : CodeVisitor {
set_attributes (method, attrs);
- foreach (FormalParameter param in params) {
- method.add_parameter (param);
+ foreach (TypeParameter type_param in type_param_list) {
+ method.add_type_parameter (type_param);
}
+
- if (accept (TokenType.YIELDS)) {
- method.coroutine = true;
+ foreach (FormalParameter param in params) {
+ method.add_parameter (param);
}
if (accept (TokenType.RAISES)) {
@@ -2737,6 +2788,10 @@ public class Vala.Genie.Parser : CodeVisitor {
} else if (ModifierFlags.CLASS in flags) {
method.binding = MemberBinding.CLASS;
}
+ if (ModifierFlags.ASYNC in flags) {
+ method.coroutine = true;
+ }
+
if (ModifierFlags.NEW in flags) {
method.hides = true;
}
@@ -2869,6 +2924,10 @@ public class Vala.Genie.Parser : CodeVisitor {
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
prop.external = true;
}
+
+ if (ModifierFlags.ASYNC in flags) {
+ Report.error (prop.source_reference, "async properties are not supported yet");
+ }
if (accept (TokenType.ASSIGN)) {
prop.default_expression = parse_expression ();
@@ -2902,8 +2961,8 @@ public class Vala.Genie.Parser : CodeVisitor {
if (readonly) {
throw new ParseError.SYNTAX (get_error ("set block not allowed for a read only property"));
}
- _construct = accept (TokenType.CONSTRUCT);
- } else if (accept (TokenType.CONSTRUCT)) {
+ _construct = (context.profile == Profile.GOBJECT) && accept (TokenType.CONSTRUCT);
+ } else if (context.profile == Profile.GOBJECT && accept (TokenType.CONSTRUCT)) {
_construct = true;
} else if (!accept (TokenType.EOL)) {
throw new ParseError.SYNTAX (get_error ("expected get, set, or construct"));
@@ -2956,6 +3015,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var field_type = prop.property_type.copy ();
prop.field = new Field ("_%s".printf (prop.name), field_type, prop.default_expression, prop.source_reference);
prop.field.access = SymbolAccessibility.PRIVATE;
+ prop.field.binding = prop.binding;
}
}
@@ -3003,11 +3063,19 @@ public class Vala.Genie.Parser : CodeVisitor {
}
set_attributes (sig, attrs);
+ if (ModifierFlags.STATIC in flags) {
+ throw new ParseError.SYNTAX (get_error ("`static' modifier not allowed on signals"));
+ } else if (ModifierFlags.CLASS in flags) {
+ throw new ParseError.SYNTAX (get_error ("`class' modifier not allowed on signals"));
+ }
+
foreach (FormalParameter formal_param in params) {
sig.add_parameter (formal_param);
}
- expect_terminator ();
+ if (!accept_terminator ()) {
+ sig.body = parse_block ();
+ }
return sig;
}
@@ -3165,6 +3233,8 @@ public class Vala.Genie.Parser : CodeVisitor {
iface.add_signal ((Vala.Signal) sym);
} else if (sym is Field) {
iface.add_field ((Field) sym);
+ } else if (sym is Constant) {
+ iface.add_constant ((Constant) sym);
} else if (sym is Property) {
iface.add_property ((Property) sym);
} else {
@@ -3270,6 +3340,7 @@ public class Vala.Genie.Parser : CodeVisitor {
while (sym.inner != null) {
sym = sym.inner;
var ns = new Namespace (sym.name, ed.source_reference);
+
if (result is Namespace) {
ns.add_namespace ((Namespace) result);
} else {
@@ -3319,6 +3390,10 @@ public class Vala.Genie.Parser : CodeVisitor {
next ();
flags |= ModifierFlags.ABSTRACT;
break;
+ case TokenType.ASYNC:
+ next ();
+ flags |= ModifierFlags.ASYNC;
+ break;
case TokenType.CLASS:
next ();
flags |= ModifierFlags.CLASS;
@@ -3425,9 +3500,6 @@ 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 ());
@@ -3520,6 +3592,7 @@ public class Vala.Genie.Parser : CodeVisitor {
while (sym.inner != null) {
sym = sym.inner;
var ns = new Namespace (sym.name, d.source_reference);
+
if (result is Namespace) {
ns.add_namespace ((Namespace) result);
} else {
diff --git a/vala/valageniescanner.vala b/vala/valageniescanner.vala
index e39191c..718a70b 100644
--- a/vala/valageniescanner.vala
+++ b/vala/valageniescanner.vala
@@ -226,7 +226,14 @@ public class Vala.Genie.Scanner {
case 5:
switch (begin[0]) {
case 'a':
- if (matches (begin, "array")) return TokenType.ARRAY;
+ switch (begin[1]) {
+ case 'r':
+ if (matches (begin, "array")) return TokenType.ARRAY;
+ break;
+ case 's':
+ if (matches (begin, "async")) return TokenType.ASYNC;
+ break;
+ }
break;
case 'b':
if (matches (begin, "break")) return TokenType.BREAK;
@@ -346,9 +353,6 @@ public class Vala.Genie.Scanner {
case 't':
if (matches (begin, "typeof")) return TokenType.TYPEOF;
break;
- case 'y':
- if (matches (begin, "yields")) return TokenType.YIELDS;
- break;
}
break;
case 7:
@@ -884,7 +888,24 @@ public class Vala.Genie.Scanner {
if (current[0] == '\\') {
current++;
token_length_in_chars++;
- if (current < end && current[0] == 'x') {
+ if (current >= end) {
+ break;
+ }
+
+ switch (current[0]) {
+ case '\'':
+ case '"':
+ case '\\':
+ case '0':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ current++;
+ token_length_in_chars++;
+ break;
+ case 'x':
// hexadecimal escape character
current++;
token_length_in_chars++;
@@ -892,9 +913,10 @@ public class Vala.Genie.Scanner {
current++;
token_length_in_chars++;
}
- } else {
- current++;
- token_length_in_chars++;
+ break;
+ default:
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "invalid escape sequence");
+ break;
}
} else if (current[0] == '\n') {
break;
@@ -904,6 +926,7 @@ public class Vala.Genie.Scanner {
current += u.to_utf8 (null);
token_length_in_chars++;
} else {
+ current++;
Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "invalid UTF-8 character");
}
}
@@ -978,7 +1001,7 @@ public class Vala.Genie.Scanner {
}
bool matches (char* begin, string keyword) {
- char* keyword_array = keyword;
+ char* keyword_array = (char *) keyword;
long len = keyword.len ();
for (int i = 0; i < len; i++) {
if (begin[i] != keyword_array[i]) {
@@ -997,7 +1020,7 @@ public class Vala.Genie.Scanner {
column++;
}
- if ((column == 1) && (current[0] == '#')) {
+ if ((column == 1) && (current < end) && (current[0] == '#')) {
pp_directive ();
return true;
}
diff --git a/vala/valagenietokentype.vala b/vala/valagenietokentype.vala
index 7009029..a814ade 100644
--- a/vala/valagenietokentype.vala
+++ b/vala/valagenietokentype.vala
@@ -39,6 +39,7 @@ public enum Vala.Genie.TokenType {
ASSIGN_PERCENT,
ASSIGN_SHIFT_LEFT,
ASSIGN_SUB,
+ ASYNC,
BITWISE_AND,
BITWISE_OR,
BREAK,
@@ -163,8 +164,7 @@ public enum Vala.Genie.TokenType {
WHEN,
WHILE,
WRITEONLY,
- YIELD,
- YIELDS;
+ YIELD;
public weak string to_string () {
switch (this) {
@@ -182,6 +182,7 @@ public enum Vala.Genie.TokenType {
case ASSIGN_PERCENT: return "`%='";
case ASSIGN_SHIFT_LEFT: return "`<<='";
case ASSIGN_SUB: return "`-='";
+ case ASYNC: return "`async'";
case BITWISE_AND: return "`&'";
case BITWISE_OR: return "`|'";
case BREAK: return "`break'";
@@ -306,7 +307,6 @@ public enum Vala.Genie.TokenType {
case WHILE: return "`while'";
case WRITEONLY: return "`writeonly'";
case YIELD: return "`yield'";
- case YIELDS: return "`yields'";
default: return "unknown token";
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]