Global variables (#378)

* global variables

* implemented type checking of global variable, added test case

* added a comment

* improvements based on Dave's suggestions

* improvements based on Jon's suggestions

* added test cases about global variable ordering
This commit is contained in:
Jeremy G. Siek
2021-03-15 16:06:27 -04:00
committed by GitHub
parent 41786eae25
commit ced98ef021
22 changed files with 822 additions and 3 deletions
+8
View File
@@ -37,6 +37,14 @@ EXAMPLES = [
"fun5",
"fun6_fail_type",
"funptr1",
"global_variable1",
"global_variable2",
"global_variable3",
"global_variable4",
"global_variable5",
"global_variable6",
"global_variable7",
"global_variable8",
"if1",
"if2",
"if3",
+9
View File
@@ -28,4 +28,13 @@ void ChoiceDeclaration::Print() const {
std::cout << "}" << std::endl;
}
// Print a global variable declaration to standard out.
void VariableDeclaration::Print() const {
std::cout << "var ";
PrintExp(type);
std::cout << " : " << name << " = ";
PrintExp(initializer);
std::cout << std::endl;
}
} // namespace Carbon
+31
View File
@@ -38,10 +38,18 @@ class Declaration {
public: // Declaration concept API, in addition to ValueSemantic.
void Print() const { box->Print(); }
auto Name() const -> std::string { return box->Name(); }
// Signals a type error if the declaration is not well typed,
// otherwise returns this declaration with annotated types.
//
// - Parameter env: types of run-time names.
// - Paraemter ct_env: values of compile-time names.
auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration {
return box->TypeChecked(env, ct_env);
}
// Add an entry in the runtime global symbol table for this declaration.
void InitGlobals(Env& globals) const { return box->InitGlobals(globals); }
// Add an entry in the compile time global symbol tables for this declaration.
auto TopLevel(ExecutionEnvironment& e) const -> void {
return box->TopLevel(e);
}
@@ -130,6 +138,29 @@ struct ChoiceDeclaration {
auto TopLevel(ExecutionEnvironment&) const -> void;
};
// Global variable definition implements the Declaration concept.
class VariableDeclaration {
public:
VariableDeclaration(int sourceLocation, std::string name, Expression* type,
Expression* initializer)
: sourceLocation(sourceLocation),
name(name),
type(type),
initializer(initializer) {}
void Print() const;
auto Name() const -> std::string;
auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
void InitGlobals(Env& globals) const;
auto TopLevel(ExecutionEnvironment&) const -> void;
private:
int sourceLocation;
std::string name;
Expression* type;
Expression* initializer;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
@@ -304,6 +304,14 @@ auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
globals.Set(definition->name, a);
}
// Adds an entry in `globals` mapping the variable's name to the
// result of evaluating the initializer.
auto VariableDeclaration::InitGlobals(Env& globals) const -> void {
auto v = InterpExp(globals, initializer);
Address a = AllocateValue(v);
globals.Set(name, a);
}
// { S, H} -> { { C, E, F} :: S, H}
// where C is the body of the function,
// E is the environment (functions + parameters + locals)
@@ -620,6 +620,9 @@ auto StructDeclaration::Name() const -> std::string { return *definition.name; }
auto ChoiceDeclaration::Name() const -> std::string { return name; }
// Returns the name of the declared variable.
auto VariableDeclaration::Name() const -> std::string { return name; }
auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
-> Declaration {
auto fields = new std::list<Member*>();
@@ -642,6 +645,19 @@ auto ChoiceDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
return *this; // TODO.
}
// Signals a type error if the initializing expression does not have
// the declared type of the variable, otherwise returns this
// declaration with annotated types.
auto VariableDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
-> Declaration {
TCResult typeCheckedInitializer =
TypeCheckExp(initializer, env, ct_env, nullptr, TCContext::ValueContext);
Value* declaredType = ToType(sourceLocation, InterpExp(ct_env, type));
ExpectType(sourceLocation, "initializer of variable", declaredType,
typeCheckedInitializer.type);
return *this;
}
auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env> {
ExecutionEnvironment tops;
bool found_main = false;
@@ -687,4 +703,11 @@ auto ChoiceDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
tops.first.Set(Name(), ct);
}
// Associate the variable name with it's declared type in the
// compile-time symbol table.
auto VariableDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
Value* declaredType = ToType(sourceLocation, InterpExp(tops.second, type));
tops.first.Set(Name(), declaredType);
}
} // namespace Carbon
+11 -3
View File
@@ -86,6 +86,7 @@ void yy::parser::error(
%type <Carbon::Expression*> return_type
%type <Carbon::Expression*> paren_expression
%type <Carbon::Expression*> tuple
%type <Carbon::Member*> variable_declaration
%type <Carbon::Member*> member
%type <std::list<Carbon::Member*>*> member_list
%type <Carbon::FieldList*> field
@@ -321,9 +322,11 @@ function_declaration:
FN identifier tuple return_type ";"
{ $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
;
member:
VAR expression ":" identifier ";"
{ $$ = MakeField(yylineno, $4, $2); }
variable_declaration: expression ":" identifier
{ $$ = MakeField(yylineno, $3, $1); }
;
member: VAR variable_declaration ";"
{ $$ = $2; }
;
member_list:
// Empty
@@ -368,6 +371,11 @@ declaration:
$$ = new Carbon::Declaration(
Carbon::ChoiceDeclaration{yylineno, $2, std::list(*$4)});
}
| VAR variable_declaration "=" expression ";"
{
$$ = new Carbon::Declaration(
Carbon::VariableDeclaration(yylineno, *$2->u.field.name, $2->u.field.type, $4));
}
;
declaration_list:
// Empty
+11
View File
@@ -0,0 +1,11 @@
// 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
// Test global variable initialization and read.
var Int: zero = 0;
fn main() -> Int {
return zero;
}
+77
View File
@@ -0,0 +1,77 @@
********** source program **********
var Int : zero = 0
fn main () -> Int {
return zero;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
var Int : zero = 0
fn main () -> Int {
return zero;
}
********** starting execution **********
********** initializing globals **********
--- step exp 0 --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return zero;<-1>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step stmt return zero; --->
{
stack: main{zero<-1> :: return zero;<0>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step exp zero --->
{
stack: main{0<-1> :: return zero;<0>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- handle value 0 with return zero;<1>(0,) --->
{
stack: top{0<-1>}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
result: 0
+17
View File
@@ -0,0 +1,17 @@
// 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
// Test that mutations to a global variable in one function is visible
// in another function.
var Int: flag = 1;
fn flipFlag() -> () {
flag = 0;
}
fn main() -> Int {
flipFlag();
return flag;
}
+193
View File
@@ -0,0 +1,193 @@
********** source program **********
var Int : flag = 1
fn flipFlag () -> () {
flag = 0;
}
fn main () -> Int {
flipFlag();
return flag;
}
********** type checking **********
--- step exp Int --->
--- step exp () --->
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
--- step exp Int --->
********** type checking complete **********
var Int : flag = 1
fn flipFlag () -> () {
flag = 0;
return ();
}
fn main () -> Int {
flipFlag();
return flag;
}
********** starting execution **********
********** initializing globals **********
--- step exp 1 --->
--- step exp () --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{flipFlag(); ... <-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step stmt flipFlag(); ... --->
{
stack: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step stmt flipFlag(); --->
{
stack: main{flipFlag()<-1> :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp flipFlag() --->
{
stack: main{flipFlag<-1> :: flipFlag()<0> :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp flipFlag --->
{
stack: main{fun<flipFlag><-1> :: flipFlag()<0> :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value fun<flipFlag> with flipFlag()<1>(fun<flipFlag>,) --->
{
stack: main{()<-1> :: flipFlag()<1>(fun<flipFlag>,) :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp () --->
{
stack: main{()<-1> :: flipFlag()<1>(fun<flipFlag>,) :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value () with flipFlag()<2>(fun<flipFlag>,(),) --->
pattern_match((), ())
{
stack: flipFlag{flag = 0; ... <-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step stmt flag = 0; ... --->
{
stack: flipFlag{flag = 0;<-1> :: return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step stmt flag = 0; --->
{
stack: flipFlag{flag<-1> :: flag = 0;<0> :: return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step lvalue flag --->
{
stack: flipFlag{ptr<0><-1> :: flag = 0;<0> :: return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value ptr<0> with flag = 0;<1>(ptr<0>,) --->
{
stack: flipFlag{0<-1> :: flag = 0;<1>(ptr<0>,) :: return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- step exp 0 --->
{
stack: flipFlag{0<-1> :: flag = 0;<1>(ptr<0>,) :: return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 1, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 1,
}
--- handle value 0 with flag = 0;<2>(ptr<0>,0,) --->
{
stack: flipFlag{return ();<-1>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- step stmt return (); --->
{
stack: flipFlag{()<-1> :: return ();<0>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- step exp () --->
{
stack: flipFlag{()<-1> :: return ();<0>} :: main{flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- handle value () with return ();<1>((),) --->
{
stack: main{()<-1> :: flipFlag();<-1> :: return flag;<-1>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- handle value () with flipFlag();<0>((),) --->
{
stack: main{return flag;<-1>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- step stmt return flag; --->
{
stack: main{flag<-1> :: return flag;<0>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- step exp flag --->
{
stack: main{0<-1> :: return flag;<0>} :: top{}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
--- handle value 0 with return flag;<1>(0,) --->
{
stack: top{0<-1>}
heap: 0, fun<flipFlag>, fun<main>,
env: main: fun<main>, flipFlag: fun<flipFlag>, flag: 0,
}
result: 0
+11
View File
@@ -0,0 +1,11 @@
// 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
// Test type checking of global variable. Error expected.
var Int: flag = true;
fn main() -> Int {
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
********** source program **********
var Int : flag = true
fn main () -> Int {
return 0;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
7: type error in initializer of variable
expected: Int
actual: Bool
EXIT CODE: 255
+12
View File
@@ -0,0 +1,12 @@
// 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
// Test mutation of a global variable.
var Int: zero = 1;
fn main() -> Int {
zero = 0;
return zero;
}
+115
View File
@@ -0,0 +1,115 @@
********** source program **********
var Int : zero = 1
fn main () -> Int {
zero = 0;
return zero;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
var Int : zero = 1
fn main () -> Int {
zero = 0;
return zero;
}
********** starting execution **********
********** initializing globals **********
--- step exp 1 --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{zero = 0; ... <-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step stmt zero = 0; ... --->
{
stack: main{zero = 0;<-1> :: return zero;<-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step stmt zero = 0; --->
{
stack: main{zero<-1> :: zero = 0;<0> :: return zero;<-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step lvalue zero --->
{
stack: main{ptr<0><-1> :: zero = 0;<0> :: return zero;<-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- handle value ptr<0> with zero = 0;<1>(ptr<0>,) --->
{
stack: main{0<-1> :: zero = 0;<1>(ptr<0>,) :: return zero;<-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- step exp 0 --->
{
stack: main{0<-1> :: zero = 0;<1>(ptr<0>,) :: return zero;<-1>} :: top{}
heap: 1, fun<main>,
env: main: fun<main>, zero: 1,
}
--- handle value 0 with zero = 0;<2>(ptr<0>,0,) --->
{
stack: main{return zero;<-1>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step stmt return zero; --->
{
stack: main{zero<-1> :: return zero;<0>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- step exp zero --->
{
stack: main{0<-1> :: return zero;<0>} :: top{}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
--- handle value 0 with return zero;<1>(0,) --->
{
stack: top{0<-1>}
heap: 0, fun<main>,
env: main: fun<main>, zero: 0,
}
result: 0
+15
View File
@@ -0,0 +1,15 @@
// 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
// Test overshadowing of global variable.
var Int: x = 1;
fn identity(Int: x) {
return x;
}
fn main() -> Int {
return identity(0);
}
+22
View File
@@ -0,0 +1,22 @@
********** source program **********
var Int : x = 1
fn identity (0 = Int: x) -> () {
return x;
}
fn main () -> Int {
return identity(0 = 0);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
10: type error in return
expected: Tuple()
actual: Int
EXIT CODE: 255
+13
View File
@@ -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
// Test a global variable depending on another global.
var Int: x = 0;
var Int: y = x;
fn main() -> Int {
return y;
}
+82
View File
@@ -0,0 +1,82 @@
********** source program **********
var Int : x = 0
var Int : y = x
fn main () -> Int {
return y;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
var Int : x = 0
var Int : y = x
fn main () -> Int {
return y;
}
********** starting execution **********
********** initializing globals **********
--- step exp 0 --->
--- step exp x --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return y;<-1>} :: top{}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- step stmt return y; --->
{
stack: main{y<-1> :: return y;<0>} :: top{}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- step exp y --->
{
stack: main{0<-1> :: return y;<0>} :: top{}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
--- handle value 0 with return y;<1>(0,) --->
{
stack: top{0<-1>}
heap: 0, 0, fun<main>,
env: main: fun<main>, y: 0, x: 0,
}
result: 0
+15
View File
@@ -0,0 +1,15 @@
// 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
// Test a global variable depending on a function.
fn f() -> Int {
return 0;
}
var Int: y = f();
fn main() -> Int {
return y;
}
+95
View File
@@ -0,0 +1,95 @@
********** source program **********
fn f () -> Int {
return 0;
}
var Int : y = f()
fn main () -> Int {
return y;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn f () -> Int {
return 0;
}
var Int : y = f()
fn main () -> Int {
return y;
}
********** starting execution **********
********** initializing globals **********
--- step exp () --->
--- step exp f() --->
--- step exp f --->
--- handle value fun<f> with f()<1>(fun<f>,) --->
--- step exp () --->
--- handle value () with f()<2>(fun<f>,(),) --->
pattern_match((), ())
--- step stmt return 0; --->
--- step exp 0 --->
--- handle value 0 with return 0;<1>(0,) --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return y;<-1>} :: top{}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- step stmt return y; --->
{
stack: main{y<-1> :: return y;<0>} :: top{}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- step exp y --->
{
stack: main{0<-1> :: return y;<0>} :: top{}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
--- handle value 0 with return y;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<f>, 0, fun<main>,
env: main: fun<main>, y: 0, f: fun<f>,
}
result: 0
+14
View File
@@ -0,0 +1,14 @@
// 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
// Test that a global variable may not depend on a later global.
// Error expected.
var Int: x = y;
var Int: y = 0;
fn main() -> Int {
return x;
}
+26
View File
@@ -0,0 +1,26 @@
********** source program **********
var Int : x = y
var Int : y = 0
fn main () -> Int {
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
var Int : x = y
var Int : y = 0
fn main () -> Int {
return x;
}
********** starting execution **********
********** initializing globals **********
--- step exp y --->
8: could not find `y`
EXIT CODE: 255