Commit 532b1966 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

support CASE, DEFAULT, DO, and SWITCH support switch and do statements add

2006-07-27  Jürg Billeter  <j@bitron.ch>

	* vala/scanner.l: support CASE, DEFAULT, DO, and SWITCH
	* vala/parser.y: support switch and do statements
	* vala/valacodevisitor.vala: add support for switch and do statements
	* vala/valadostatement.vala
	* vala/valaswitchlabel.vala
	* vala/valaswitchsection.vala
	* vala/valaswitchstatement.vala
	* vala/valastatement.vala, vala/valasymbol.vala,
	  vala/valaunaryexpression.vala, vala/valavariabledeclarator.vala,
	  vala/valawhilestatement.vala: add interface documentation, use
	  implicit namespace specification
	* vala/vala.h, vala/Makefile.am: update
	* vapi/glib-2.0.vala: don't use default keyword

svn path=/trunk/; revision=86
parent 37de41c0
2006-07-27 Jürg Billeter <j@bitron.ch>
* vala/scanner.l: support CASE, DEFAULT, DO, and SWITCH
* vala/parser.y: support switch and do statements
* vala/valacodevisitor.vala: add support for switch and do statements
* vala/valadostatement.vala
* vala/valaswitchlabel.vala
* vala/valaswitchsection.vala
* vala/valaswitchstatement.vala
* vala/valastatement.vala, vala/valasymbol.vala,
vala/valaunaryexpression.vala, vala/valavariabledeclarator.vala,
vala/valawhilestatement.vala: add interface documentation, use
implicit namespace specification
* vala/vala.h, vala/Makefile.am: update
* vapi/glib-2.0.vala: don't use default keyword
2006-07-27 Jürg Billeter <j@bitron.ch>
* vala/parser.y: support for loops with local variable declaration in
......
......@@ -86,6 +86,9 @@ libvala_la_SOURCES = \
valadestructor.c \
valadestructor.h \
valadestructor.vala \
valadostatement.c \
valadostatement.h \
valadostatement.vala \
valaemptystatement.c \
valaemptystatement.h \
valaemptystatement.vala \
......@@ -230,6 +233,15 @@ libvala_la_SOURCES = \
valastruct.c \
valastruct.h \
valastruct.vala \
valaswitchlabel.c \
valaswitchlabel.h \
valaswitchlabel.vala \
valaswitchsection.c \
valaswitchsection.h \
valaswitchsection.vala \
valaswitchstatement.c \
valaswitchstatement.h \
valaswitchstatement.vala \
valasymbolbuilder.c \
valasymbolbuilder.h \
valasymbolbuilder.vala \
......
......@@ -91,6 +91,8 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
ValaTypeParameter *type_parameter;
ValaAttribute *attribute;
ValaNamedArgument *named_argument;
ValaSwitchSection *switch_section;
ValaSwitchLabel *switch_label;
}
%token OPEN_BRACE "{"
......@@ -150,10 +152,13 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%token ABSTRACT "abstract"
%token BREAK "break"
%token CALLBACK "callback"
%token CASE "case"
%token CLASS "class"
%token CONST "const"
%token CONSTRUCT "construct"
%token CONTINUE "continue"
%token DEFAULT "default"
%token DO "do"
%token ELSE "else"
%token ENUM "enum"
%token VALA_FALSE "false"
......@@ -173,11 +178,12 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%token PUBLIC "public"
%token PRIVATE "private"
%token REF "ref"
%token RETURN "return"
%token SET "set"
%token SIGNAL "signal"
%token STATIC "static"
%token STRUCT "struct"
%token RETURN "return"
%token SWITCH "switch"
%token VALA_TRUE "true"
%token TYPEOF "typeof"
%token USING "using"
......@@ -245,8 +251,16 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%type <expression> statement_expression
%type <statement> selection_statement
%type <statement> if_statement
%type <statement> switch_statement
%type <list> switch_block
%type <list> opt_switch_sections
%type <list> switch_sections
%type <switch_section> switch_section
%type <list> switch_labels
%type <switch_label> switch_label
%type <statement> iteration_statement
%type <statement> while_statement
%type <statement> do_statement
%type <statement> for_statement
%type <list> opt_statement_expression_list
%type <list> statement_expression_list
......@@ -1107,7 +1121,7 @@ local_variable_declaration
g_object_unref (src);
for (l = $2; l != NULL; l = l->next) {
ValaVariableDeclarator *decl = l->data;
decl->type_reference = g_object_ref ($1);
vala_variable_declarator_set_type_reference (decl, g_object_ref ($1));
vala_local_variable_declaration_add_declarator ($$, decl);
g_object_unref (decl);
}
......@@ -1200,6 +1214,7 @@ statement_expression
selection_statement
: if_statement
| switch_statement
;
if_statement
......@@ -1222,8 +1237,102 @@ if_statement
}
;
switch_statement
: comment SWITCH OPEN_PARENS expression CLOSE_PARENS switch_block
{
ValaSourceReference *src = src_com(@4, $1);
$$ = VALA_STATEMENT (vala_switch_statement_new ($4, src));
g_object_unref ($4);
g_object_unref (src);
if ($6 != NULL) {
GList *l;
for (l = $6; l != NULL; l = l->next) {
vala_switch_statement_add_section (VALA_SWITCH_STATEMENT ($$), l->data);
g_object_unref (l->data);
}
g_list_free ($6);
}
}
;
switch_block
: OPEN_BRACE opt_switch_sections CLOSE_BRACE
{
$$ = $2;
}
;
opt_switch_sections
: /* empty */
{
$$ = NULL;
}
| switch_sections
;
switch_sections
: switch_section
{
$$ = g_list_append (NULL, $1);
}
| switch_sections switch_section
{
$$ = g_list_append ($1, $2);
}
;
switch_section
: comment switch_labels statement_list
{
ValaSourceReference *src = src_com(@2, $1);
$$ = vala_switch_section_new (src);
g_object_unref (src);
GList *l;
for (l = $2; l != NULL; l = l->next) {
vala_switch_section_add_label ($$, l->data);
g_object_unref (l->data);
}
g_list_free ($2);
for (l = $3; l != NULL; l = l->next) {
vala_switch_section_add_statement ($$, l->data);
g_object_unref (l->data);
}
g_list_free ($3);
}
;
switch_labels
: switch_label
{
$$ = g_list_append (NULL, $1);
}
| switch_labels switch_label
{
$$ = g_list_append ($1, $2);
}
;
switch_label
: CASE expression COLON
{
ValaSourceReference *src = src(@2);
$$ = vala_switch_label_new ($2, src);
g_object_unref ($2);
g_object_unref (src);
}
| DEFAULT COLON
{
ValaSourceReference *src = src(@1);
$$ = vala_switch_label_new_default (src);
g_object_unref (src);
}
;
iteration_statement
: while_statement
| do_statement
| for_statement
| foreach_statement
;
......@@ -1239,6 +1348,17 @@ while_statement
}
;
do_statement
: DO embedded_statement WHILE OPEN_PARENS expression CLOSE_PARENS SEMICOLON
{
ValaSourceReference *src = src(@1);
$$ = VALA_STATEMENT (vala_do_statement_new ($2, $5, src));
g_object_unref ($2);
g_object_unref ($5);
g_object_unref (src);
}
;
for_statement
: FOR OPEN_PARENS opt_statement_expression_list SEMICOLON opt_expression SEMICOLON opt_statement_expression_list CLOSE_PARENS embedded_statement
{
......@@ -1288,7 +1408,7 @@ for_statement
if (init != NULL) {
ValaSourceReference *decl_src = vala_code_node_get_source_reference (VALA_CODE_NODE (decl));
ValaMemberAccess *lhs = vala_member_access_new (NULL, vala_variable_declarator_get_name (decl), decl_src);
ValaAssignment *assign = vala_assignment_new (lhs, VALA_ASSIGNMENT_OPERATOR_SIMPLE, init, decl_src);
ValaAssignment *assign = vala_assignment_new (VALA_EXPRESSION (lhs), VALA_ASSIGNMENT_OPERATOR_SIMPLE, init, decl_src);
g_object_unref (lhs);
vala_for_statement_add_initializer (for_statement, VALA_EXPRESSION (assign));
g_object_unref (assign);
......
......@@ -117,10 +117,13 @@ literal ({literal_integer}|{literal_real}|{literal_character}|{literal_string}
"abstract" { uploc; return ABSTRACT; }
"break" { uploc; return BREAK; }
"callback" { uploc; return CALLBACK; }
"case" { uploc; return CASE; }
"class" { uploc; return CLASS; }
"const" { uploc; return CONST; }
"construct" { uploc; return CONSTRUCT; }
"continue" { uploc; return CONTINUE; }
"default" { uploc; return DEFAULT; }
"do" { uploc; return DO; }
"else" { uploc; return ELSE; }
"enum" { uploc; return ENUM; }
"false" { uploc; return VALA_FALSE; }
......@@ -144,6 +147,7 @@ literal ({literal_integer}|{literal_real}|{literal_character}|{literal_string}
"signal" { uploc; return SIGNAL; }
"static" { uploc; return STATIC; }
"struct" { uploc; return STRUCT; }
"switch" { uploc; return SWITCH; }
"return" { uploc; return RETURN; }
"true" { uploc; return VALA_TRUE; }
"typeof" { uploc; return TYPEOF; }
......
......@@ -15,6 +15,7 @@
#include <vala/valacontinuestatement.h>
#include <vala/valadeclarationstatement.h>
#include <vala/valadestructor.h>
#include <vala/valadostatement.h>
#include <vala/valaemptystatement.h>
#include <vala/valaenum.h>
#include <vala/valaenumvalue.h>
......@@ -52,6 +53,9 @@
#include <vala/valasourcereference.h>
#include <vala/valastringliteral.h>
#include <vala/valastruct.h>
#include <vala/valaswitchlabel.h>
#include <vala/valaswitchsection.h>
#include <vala/valaswitchstatement.h>
#include <vala/valatypecheck.h>
#include <vala/valatypeofexpression.h>
#include <vala/valatypeparameter.h>
......
......@@ -46,11 +46,11 @@ public class Vala.BinaryExpression : Expression {
/**
* Creates a new binary expression.
*
* @param op binary operator
* @param left left operand
* @param right right operand
* @param op binary operator
* @param left left operand
* @param right right operand
* @param source reference to source code
* @return newly created binary expression
* @return newly created binary expression
*/
public static ref BinaryExpression! new (BinaryOperator op, Expression! left, Expression! right, SourceReference source) {
return (new BinaryExpression (operator = op, left = left, right = right, source_reference = source));
......
......@@ -395,6 +395,30 @@ public abstract class Vala.CodeVisitor {
public virtual void visit_if_statement (IfStatement! stmt) {
}
/**
* Visit operation called for switch statements.
*
* @param stmt a switch statement
*/
public virtual void visit_switch_statement (SwitchStatement! stmt) {
}
/**
* Visit operation called for switch sections.
*
* @param section a switch section
*/
public virtual void visit_switch_section (SwitchSection! section) {
}
/**
* Visit operation called for switch label.
*
* @param label a switch label
*/
public virtual void visit_switch_label (SwitchLabel! label) {
}
/**
* Visit operation called for while statements.
*
......@@ -403,6 +427,14 @@ public abstract class Vala.CodeVisitor {
public virtual void visit_while_statement (WhileStatement! stmt) {
}
/**
* Visit operation called for do statements.
*
* @param stmt a do statement
*/
public virtual void visit_do_statement (DoStatement! stmt) {
}
/**
* Visit operation called for for statements.
*
......
/* valadostatement.vala
*
* Copyright (C) 2006 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Jürg Billeter <j@bitron.ch>
*/
using GLib;
/**
* Represents a do iteration statement in the source code.
*/
public class Vala.DoStatement : Statement {
/**
* Specifies the loop body.
*/
public Statement body { get; set; }
/**
* Specifies the loop condition.
*/
public Expression condition { get; set; }
/**
* Creates a new do statement.
*
* @param cond loop condition
* @param body loop body
* @param source reference to source code
* @return newly created do statement
*/
public static ref DoStatement! new (Statement! body, Expression! cond, SourceReference source) {
return (new DoStatement (body = body, condition = cond, source_reference = source));
}
public override void accept (CodeVisitor! visitor) {
body.accept (visitor);
condition.accept (visitor);
visitor.visit_end_full_expression (condition);
visitor.visit_do_statement (this);
}
}
......@@ -22,7 +22,8 @@
using GLib;
namespace Vala {
public abstract class Statement : CodeNode {
}
/**
* Base class for all statement types.
*/
public abstract class Vala.Statement : CodeNode {
}
/* valaswitchlabel.vala
*
* Copyright (C) 2006 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Jürg Billeter <j@bitron.ch>
*/
using GLib;
/**
* Represents a switch label in the source code.
*/
public class Vala.SwitchLabel : CodeNode {
/**
* Specifies the label expression.
*/
public Expression expression { get; set; }
/**
* Creates a new switch case label.
*
* @param expr label expression
* @param source reference to source code
* @return newly created switch case label
*/
public static ref SwitchLabel! new (Expression expr, SourceReference source) {
return (new SwitchLabel (expression = expr, source_reference = source));
}
/**
* Creates a new switch default label.
*
* @param source reference to source code
* @return newly created switch default label
*/
public static ref SwitchLabel! new_default (SourceReference source) {
return (new SwitchLabel (source_reference = source));
}
public override void accept (CodeVisitor! visitor) {
if (expression != null) {
expression.accept (visitor);
visitor.visit_end_full_expression (expression);
}
visitor.visit_switch_label (this);
}
}
/* valaswitchsection.vala
*
* Copyright (C) 2006 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Jürg Billeter <j@bitron.ch>
*/
using GLib;
/**
* Represents a switch section in the source code.
*/
public class Vala.SwitchSection : CodeNode {
private List<SwitchLabel> labels;
private List<Statement> statement_list;
/**
* Creates a new switch section.
*
* @param source reference to source code
* @return newly created switch section
*/
public static ref SwitchSection! new (SourceReference source) {
return (new SwitchSection (source_reference = source));
}
/**
* Appends the specified label to the list of switch labels.
*
* @param label a switch label
*/
public void add_label (SwitchLabel! label) {
labels.append (label);
}
/**
* Returns a copy of the list of switch labels.
*
* @return switch label list
*/
public ref List<SwitchLabel> get_labels () {
return labels.copy ();
}
/**
* Appends the specified statement to this switch section.
*
* @param stmt a statement
*/
public void add_statement (Statement! stmt) {
statement_list.append (stmt);
}
public override void accept (CodeVisitor! visitor) {
foreach (SwitchLabel label in labels) {
label.accept (visitor);
}
foreach (Statement st in statement_list) {
st.accept (visitor);
}
visitor.visit_switch_section (this);
}
}
/* valaswitchstatement.vala
*
* Copyright (C) 2006 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Jürg Billeter <j@bitron.ch>
*/
using GLib;
/**
* Represents a switch selection statement in the source code.
*/
public class Vala.SwitchStatement : Statement {
/**
* Specifies the switch expression.
*/
public Expression! expression { get; set construct; }
private List<SwitchSection> sections;
/**
* Creates a new switch statement.
*
* @param expr switch expression
* @param source reference to source code
* @return newly created switch statement
*/
public static ref SwitchStatement! new (Expression! expr, SourceReference source) {
return (new SwitchStatement (expression = expr, source_reference = source));
}
/**
* Appends the specified section to the list of switch sections.
*
* @param section a switch section
*/
public void add_section (SwitchSection! section) {
sections.append (section);
}
public override void accept (CodeVisitor! visitor) {
expression.accept (visitor);
visitor.visit_end_full_expression (expression);
foreach (SwitchSection section in sections) {
section.accept (visitor);
}
visitor.visit_switch_statement (this);
}
}
......@@ -22,47 +22,88 @@
using GLib;
namespace Vala {
public class Symbol {
HashTable<string,Symbol> symbol_table = HashTable.new_full (str_hash, str_equal, g_free, g_object_unref);
public weak CodeNode node { get; construct; }
public weak Symbol parent_symbol;
public string name;
/* used for local variables not declared at the beginning of the
* block to determine which variables need to be freed before
* jump statements
*/
public bool active = true;
public ref string get_full_name () {
if (parent_symbol == null) {
return name;
}
if (name == null) {
return parent_symbol.get_full_name ();
}
/**
* Represents a node in the symbol tree.
*/
public class Vala.Symbol {
/**
* The code node that created this symbol, if applicable.
*/
public weak CodeNode node { get; set; }
/**
* The parent of this symbol.
*/
public weak Symbol parent_symbol { get; set; }
/**
* The symbol name.
*/
public string name { get; set; }
if (parent_symbol.get_full_name () == null) {
return name;
}
return "%s.%s".printf (parent_symbol.get_full_name (), name);
/**
* Specifies whether this symbol is active.
*
* Symbols may become inactive when they only apply to a part of a
* scope. This is used for local variables not declared at the beginning
* of the block to determine which variables need to be freed before
* jump statements.
*/
public bool active { get; set; }
private HashTable<string,Symbol> symbol_table = HashTable.new_full (str_hash, str_equal, g_free, g_object_unref);
Symbol () {
active = true;
}
/**
* Returns the fully expanded name of this symbol for use in
* human-readable messages.
*
* @return full name
*/
public ref string get_full_name () {
if (parent_symbol == null) {
return name;
}
public void add (string s, Symbol sym) {
symbol_table.insert (s, sym);
sym.parent_symbol = this;
sym.name = s;
if (name == null) {
return parent_symbol.get_full_name ();
}
if (parent_symbol.get_full_name () == null) {
return name;
}
public Symbol lookup (string s) {
Symbol sym = symbol_table.lookup (s);
if (sym != null && !sym.active) {
sym = null;
}
return sym;
return "%s.%s".printf (parent_symbol.get_full_name (), name);
}
/**
* Adds the specified symbol with the specified name to the symbol table
* of this symbol.
*
* @param name name for the specified symbol
* @param sym a symbol
*/
public void add (string! name, Symbol! sym) {
symbol_table.insert (name, sym);
sym.parent_symbol = this;
sym.name = name;
}
/**
* Returns the symbol stored in the symbol table with the specified
* name.
*
* @param name name of the symbol to be returned
* @return found symbol or null
*/
public Symbol lookup (string! name) {
Symbol sym = symbol_table.lookup (name);
if (sym != null && !sym.active) {
sym = null;
}
return sym;
}
}