Bläddra i källkod

adding optional else to executable semantics (#295)

* adding comments and some newlines

* added optonal else
Jeremy G. Siek 5 år sedan
förälder
incheckning
3ea84c9276

+ 3 - 0
executable_semantics/BUILD

@@ -72,6 +72,9 @@ EXAMPLES = [
     "fun5",
     "fun6_fail_type",
     "funptr1",
+    "if1",
+    "if2",
+    "if3",
     "match_int_default",
     "match_int",
     "match_type",

+ 8 - 2
executable_semantics/syntax.ypp

@@ -57,6 +57,7 @@ void yyerror(char* error) {
 %type <function_definition> function_definition
 %type <declaration_list> declaration_list
 %type <statement> statement
+%type <statement> optional_else
 %type <statement_list> statement_list
 %type <expression> expression
 %type <expression> pattern
@@ -228,8 +229,8 @@ statement:
     { $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
 | expression ';'
     { $$ = Carbon::MakeExpStmt(yylineno, $1); }
-| IF '(' expression ')' statement ELSE statement
-    { $$ = Carbon::MakeIf(yylineno, $3, $5, $7); }
+| IF '(' expression ')' statement optional_else
+    { $$ = Carbon::MakeIf(yylineno, $3, $5, $6); }
 | WHILE '(' expression ')' statement
     { $$ = Carbon::MakeWhile(yylineno, $3, $5); }
 | BREAK ';'
@@ -243,6 +244,11 @@ statement:
 | MATCH '(' expression ')' '{' clause_list '}'
     { $$ = Carbon::MakeMatch(yylineno, $3, $6); }
 ;
+optional_else:
+  // Empty
+    { $$ = 0; }
+| ELSE statement { $$ = $2; }
+;
 statement_list:
   // Empty
     { $$ = 0; }

+ 10 - 0
executable_semantics/testdata/if1.6c

@@ -0,0 +1,10 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+fn main() -> Int {
+  if (1 == 1)
+    return 0;
+
+  return 1;
+}

+ 161 - 0
executable_semantics/testdata/if1.golden

@@ -0,0 +1,161 @@
+********** source program **********
+fn main () -> Int {
+if ((1 == 1))
+return 0;
+else
+
+return 1;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((1 == 1))
+return 0;
+else
+
+return 1;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((1 == 1))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((1 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((1 == 1))
+ ... 
+else
+<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((1 == 1))
+ ... 
+else
+ --->
+{
+stack: main{(1 == 1)<-1> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (1 == 1) --->
+{
+stack: main{1<-1> :: (1 == 1)<0> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (1 == 1)<0> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (1 == 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (1 == 1)<1>(1,) :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (1 == 1)<1>(1,) :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (1 == 1)<2>(1,1,) --->
+{
+stack: main{true<-1> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value true with if ((1 == 1))
+ ... 
+else
+<1>(true,) --->
+{
+stack: main{return 0;<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+result: 0

+ 10 - 0
executable_semantics/testdata/if2.6c

@@ -0,0 +1,10 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+fn main() -> Int {
+  if (0 == 1)
+    return 1;
+
+  return 0;
+}

+ 143 - 0
executable_semantics/testdata/if2.golden

@@ -0,0 +1,143 @@
+********** source program **********
+fn main () -> Int {
+if ((0 == 1))
+return 1;
+else
+
+return 0;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((0 == 1))
+return 1;
+else
+
+return 0;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+<-1> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ --->
+{
+stack: main{(0 == 1)<-1> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 1) --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 1)<1>(0,) --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (0 == 1)<2>(0,1,) --->
+{
+stack: main{false<-1> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value false with if ((0 == 1))
+ ... 
+else
+<1>(false,) --->
+{
+stack: main{<-1> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt  --->

+ 13 - 0
executable_semantics/testdata/if3.6c

@@ -0,0 +1,13 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+fn main() -> Int {
+  if (0 == 0)
+    if (0 == 1)
+      return 1;
+    else
+      return 0;
+
+  return 1;
+}

+ 236 - 0
executable_semantics/testdata/if3.golden

@@ -0,0 +1,236 @@
+********** source program **********
+fn main () -> Int {
+if ((0 == 0))
+if ((0 == 1))
+return 1;
+else
+return 0;
+else
+
+return 1;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((0 == 0))
+if ((0 == 1))
+return 1;
+else
+return 0;
+else
+
+return 1;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((0 == 0))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((0 == 0))
+ ... 
+else
+<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 0))
+ ... 
+else
+ --->
+{
+stack: main{(0 == 0)<-1> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 0) --->
+{
+stack: main{0<-1> :: (0 == 0)<0> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 0)<0> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 0)<1>(0,) --->
+{
+stack: main{0<-1> :: (0 == 0)<1>(0,) :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 0)<1>(0,) :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 0)<2>(0,0,) --->
+{
+stack: main{true<-1> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value true with if ((0 == 0))
+ ... 
+else
+<1>(true,) --->
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+ ... <-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{(0 == 1)<-1> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 1) --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 1)<1>(0,) --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (0 == 1)<2>(0,1,) --->
+{
+stack: main{false<-1> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value false with if ((0 == 1))
+ ... 
+else
+ ... <1>(false,) --->
+{
+stack: main{return 0;<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+result: 0