Adapting jsiek's executable semantics tooling for commit. (#237)

Notes versus what jsiek wrote:

- This adopts Bazel for building.
    - System-local versions of bison/flex are used. I found https://github.com/jmillikin/rules_bison, but those print a lot of warnings (things like -Wsign-compare IIRC) which makes builds hard to read. Plus I think the underlying bison_cc_library rule didn't work, so this would really only get a hermetic bison/flex build (helpful, but didn't seem worth more time).
    - I'm adding in a .bazeliskrc to push a somewhat more standard choice of bazel versions. I noticed I was getting unstable versions by default, possible Google-specific, but seemed good to include.
    - The `-lpthread` kludge.
- Turn all of the examples into golden tests.
    - Including adding a golden test rule.
- Fixed various style guide issues. For example:
    - Fixing function names to be CamelCase instead of snake_case (https://google.github.io/styleguide/cppguide.html#Function_Names)
    - Removed exception use (https://google.github.io/styleguide/cppguide.html#Exceptions)
    - File name fixes (https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md#file-names)
- Dropped `using` of `std` names -- I believe this is preferred (maybe we should be explicit about this in the Carbon style guide)
- Switched `enum` uses to `enum class` for ease-of-identification.
- Spent some time breaking out files to hopefully be easier to read/edit pieces, and understand relations between structs.
- Added `code requires` to `syntax.ypp` to address include issues

Possibly other things -- but the fundamental structure is, I believe, unchanged. I put in the golden tests pretty early to ensure I wasn't mutating output/results.
This commit is contained in:
Jon Meow
2021-02-19 15:25:43 -08:00
committed by GitHub
parent 7670b6377c
commit 6e5070de18
97 changed files with 11896 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
# 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
USE_BAZEL_VERSION=latest
+18 -1
View File
@@ -24,6 +24,8 @@ repos:
- id: mixed-line-ending
args: ['--fix=lf']
- id: trailing-whitespace
exclude: '^(.*/testdata/.*\.golden)$'
- repo: https://github.com/google/pre-commit-tool-hooks
rev: 1d04a2848ac54d64bd6474ccec69aac45fa88414 # frozen: v1.1.1
hooks:
@@ -34,7 +36,22 @@ repos:
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
exclude: '^(website/(firebase/.firebaserc|jekyll/(Gemfile.lock|theme/.*))|.bazelversion|compile_flags.txt|.*\.def)$'
- --custom_format
- '\.6c$'
- ''
- '// '
- ''
- --custom_format
- '\.lpp$'
- '/*'
- ''
- '*/'
- --custom_format
- '\.ypp$'
- ''
- '// '
- ''
exclude: '^(website/(firebase/.firebaserc|jekyll/(Gemfile.lock|theme/.*))|.bazelversion|compile_flags.txt|.*\.def|.*/testdata/.*\.golden)$'
- id: check-google-doc-style
- id: markdown-toc
- repo: https://github.com/codespell-project/codespell
@@ -352,6 +352,8 @@ def _impl(ctx):
# paths. Those might have a system installed libc++
# and we want to find the one next to our Clang.
"-L" + llvm_bindir + "/../lib",
# Link with pthread.
"-lpthread",
],
),
]),
+5
View File
@@ -0,0 +1,5 @@
# 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
exports_files(["golden_test.sh"])
+25
View File
@@ -0,0 +1,25 @@
# 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
"""Rule for a golden test."""
def golden_test(name, golden, subject, **kwargs):
"""Compares two files. Passes if they are identical.
Args:
name: Name of the build rule.
subject: The generated file to be compared.
golden: The golden file to be compared.
**kwargs: Any additional parameters for the generated sh_test.
"""
native.sh_test(
name = name,
srcs = ["//bazel/testing:golden_test.sh"],
args = [
"$(location %s)" % golden,
"$(location %s)" % subject,
],
data = [golden, subject],
**kwargs
)
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# 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
set -e -u -o pipefail
GOLDEN=$1
SUBJECT=$2
if [[ $# == 3 && $3 == "--update" ]]; then
cp "${SUBJECT}" "${GOLDEN}"
exit $?
fi
CMD=("diff" "-u" "${GOLDEN}" "${SUBJECT}")
if "${CMD[@]}"; then
echo "PASS"
exit 0
fi
cat <<EOT
When running under:
${TEST_SRCDIR}
the golden contents of:
${GOLDEN}
do not match generated target:
${SUBJECT}
To update the golden file, run the following:
bazel run ${TEST_TARGET} -- --update
EOT
exit 1
+19
View File
@@ -23,6 +23,7 @@ contributions.
- [Cargo (optional)](#cargo-optional)
- [Main tools](#main-tools)
- [Bazel and Bazelisk](#bazel-and-bazelisk)
- [Bison and Flex](#bison-and-flex)
- [buildifier](#buildifier)
- [Clang and LLVM](#clang-and-llvm)
- [Ninja](#ninja)
@@ -151,6 +152,24 @@ Our recommended way of installing is:
brew install bazelisk
```
### Bison and Flex
[Bison](https://www.gnu.org/software/bison/) and
[Flex](https://github.com/westes/flex) are used by executable semantics.
Although we may
[switch to a hemertic toolchain later](https://github.com/carbon-language/carbon-lang/issues/266),
an install is currently required.
Our recommended way of installing is:
```bash
brew install bison flex
```
On MacOS, it will be necessary to explicitly add the installed paths to the
`PATH` environment variable so that the brew-installed versions are used instead
of Xcode-installed versions. Read `brew` output for instructions.
### buildifier
[Buildifier](https://github.com/bazelbuild/buildtools/tree/master/buildifier) is
+107
View File
@@ -0,0 +1,107 @@
# 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
# TODO(https://github.com/carbon-language/carbon-lang/issues/266):
# Migrate bison/flex usage to a more hermetic bazel build.
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("//bazel/testing:golden_test.bzl", "golden_test")
cc_binary(
name = "executable_semantics",
srcs = ["main.cpp"],
deps = [":syntax"],
)
cc_library(
name = "syntax",
srcs = [
"syntax.tab.cpp",
"syntax.yy.cpp",
"syntax_helpers.cpp",
"syntax_helpers.h",
],
hdrs = ["syntax.tab.h"],
# Disable warnings for generated code.
copts = [
"-Wno-unneeded-internal-declaration",
"-Wno-unused-function",
"-Wno-writable-strings",
],
deps = [
"//executable_semantics/ast:declaration",
"//executable_semantics/ast:expression",
"//executable_semantics/ast:expression_or_field_list",
"//executable_semantics/interpreter",
],
)
genrule(
name = "syntax_bison_srcs",
srcs = ["syntax.ypp"],
outs = [
"syntax.tab.cpp",
"syntax.tab.h",
],
cmd = "bison " +
"--output=$(location syntax.tab.cpp) " +
"--defines=$(location syntax.tab.h) " +
"$(location syntax.ypp)",
)
genrule(
name = "syntax_flex_srcs",
srcs = ["syntax.lpp"],
outs = ["syntax.yy.cpp"],
cmd = "flex " +
"--outfile=$(location syntax.yy.cpp) " +
"$(location syntax.lpp)",
)
EXAMPLES = [
"block1",
"break1",
"choice1",
"continue1",
"fun_recur",
"fun1",
"fun2",
"fun3",
"fun4",
"fun5",
"fun6_fail_type",
"funptr1",
"match_int_default",
"match_int",
"match_type",
"next",
"pattern_init",
"record1",
"struct1",
"struct2",
"struct3",
"tuple_assign",
"tuple_match",
"tuple1",
"tuple2",
"undef1",
"undef2",
"while1",
"zero",
]
[genrule(
name = "%s_out" % e,
srcs = ["testdata/%s.6c" % e],
outs = ["testdata/%s.out" % e],
# Suppress command errors.
cmd = "$(location executable_semantics) $< > $@ 2>&1 || true",
tools = [":executable_semantics"],
) for e in EXAMPLES]
[golden_test(
name = "%s_test" % e,
golden = "testdata/%s.golden" % e,
subject = "testdata/%s.out" % e,
) for e in EXAMPLES]
+133
View File
@@ -0,0 +1,133 @@
# Executable Semantics
<!--
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
-->
This directory contains a work-in-progress executable semantics. It started as
an executable semantics for Featherweight C and it is migrating into an
executable semantics for the Carbon language. It includes a parser, type
checker, and abstract machine.
This language currently includes several kinds of values: integer, booleans,
functions, and structs. A kind of safe union, called a `choice`, is in progress.
Regarding control-flow, it includes if statements, while loops, break, continue,
function calls, and a variant of `switch` called `match` is in progress.
The grammar of the language matches the one in Proposal
[#162](https://github.com/carbon-language/carbon-lang/pull/162). The type
checker and abstract machine do not yet have a corresponding proposal.
Nevertheless they are present here to help test the parser but should not be
considered definitive.
The parser is implemented using the flex and bison parser generator tools.
- [`syntax.lpp`](syntax/syntax.lpp) the lexer specification
- [`syntax.ypp`](syntax/syntax.ypp) the grammar
The parser translates program text into an abstract syntax tree (AST), defined
in the [ast](ast/) subdirectory.
The [type checker](interpreter/typecheck.h) defines what it means for an AST to
be a valid program. The type checker prints an error and exits if the AST is
invalid.
The parser and type checker together specify the static (compile-time)
semantics.
The dynamic (run-time) semantics is specified by an abstract machine. Abstract
machines have several positive characteristics that make them good for
specification:
- abstract machines operate on the AST of the program (and not some
lower-level representation such as bytecode) so they directly connect the
program to its behavior
- abstract machines can easily handle language features with complex
control-flow, such as goto, exceptions, coroutines, and even first-class
continuations.
The one down-side of abstract machines is that they are not as simple as a
definitional interpreter (a recursive function that interprets the program), but
it is more difficult to handle complex control flow in a definitional
interpreter.
[InterpProgram()](interpreter/interpreter.h) runs an abstract machine using the
[interpreter](interpreter/), as described below.
The abstract machine implements a state-transition system. The state is defined
by the `State` structure, which includes three components: the procedure call
stack, the heap, and the function definitions. The `Step` function updates the
state by executing a little bit of the program. The `Step` function is called
repeatedly to execute the entire program.
An implementation of the language (such as a compiler) must be observationally
equivalent to this abstract machine. The notion of observation is different for
each language, and can include things like input and output. This language is
currently so simple that the only thing that is observable is the final result,
an integer. So an implementation must produce the same final result as the one
produces by the abstract machine. In particular, an implementation does **not**
have to mimic each step of the abstract machine and does not have to use the
same kinds of data structures to store the state of the program.
A procedure call frame, defined by the `Frame` structure, includes a pointer to
the function being called, the environment that maps variables to their
addresses, and a to-do list of actions. Each action corresponds to an expression
or statement in the program. The `Action` structure represents an action. An
action often spawns other actions that needs to be completed first and
afterwards uses their results to complete its action. To keep track of this
process, each action includes a position field `pos` that stores an integer that
starts at `-1` and increments as the action makes progress. For example, suppose
the action associated with an addition expression `e1 + e2` is at the top of the
to-do list:
(e1 + e2) [-1] :: ...
When this action kicks off (in the `StepExp` function), it increments `pos` to
`0` and pushes `e1` onto the to-do list, so the top of the todo list now looks
like:
e1 [-1] :: (e1 + e2) [0] :: ...
Skipping over the processing of `e1`, it eventually turns into an integer value
`n1`:
n1 :: (e1 + e2) [0]
Because there is a value at the top of the to-do list, the `Step` function
invokes `HandleValue` which then dispatches on the next action on the to-do
list, in this case the addition. The addition action spawns an action for
subexpression `e2`, increments `pos` to `1`, and remembers `n1`.
e2 [-1] :: (e1 + e2) [1](n1) :: ...
Skipping over the processing of `e2`, it eventually turns into an integer value
`n2`:
n2 :: (e1 + e2) [1](n1) :: ...
Again the `Step` function invokes `HandleValue` and dispatches to the addition
action which performs the arithmetic and pushes the result on the to-do list.
Let `n3` be the sum of `n1` and `n2`.
n3 :: ...
The heap is an array of values. It is used not only for `malloc` but also to
store anything that is mutable, including function parameters and local
variables. A pointer is simply an index into the array. The `malloc` expression
causes the heap to grow (at the end) and returns the index of the last slot. The
dereference expression returns the nth value of the heap, as specified by the
dereferenced pointer. The assignment operation stores the value of the
right-hand side into the heap at the index specified by the left-hand side
lvalue.
As you might expect, function calls push a new frame on the stack and the
`return` statement pops a frame off the stack. The parameter passing semantics
is call-by-value, so the machine applies `CopyVal` to the incoming arguments and
the outgoing return value. Also, the machine is careful to kill the parameters
and local variables when the function call is complete.
The [`testdata/`](testdata/) subdirectory includes some example programs with
golden output.
+61
View File
@@ -0,0 +1,61 @@
# 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
load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//executable_semantics:__subpackages__"])
cc_library(
name = "declaration",
srcs = ["declaration.cpp"],
hdrs = ["declaration.h"],
deps = [
":function_definition",
":member",
":struct_definition",
],
)
cc_library(
name = "expression",
srcs = ["expression.cpp"],
hdrs = ["expression.h"],
)
cc_library(
name = "expression_or_field_list",
srcs = ["expression_or_field_list.cpp"],
hdrs = ["expression_or_field_list.h"],
deps = [":expression"],
)
cc_library(
name = "function_definition",
srcs = ["function_definition.cpp"],
hdrs = ["function_definition.h"],
deps = [
":expression",
":statement",
],
)
cc_library(
name = "member",
srcs = ["member.cpp"],
hdrs = ["member.h"],
deps = [":expression"],
)
cc_library(
name = "statement",
srcs = ["statement.cpp"],
hdrs = ["statement.h"],
deps = [":expression"],
)
cc_library(
name = "struct_definition",
hdrs = ["struct_definition.h"],
deps = [":member"],
)
+64
View File
@@ -0,0 +1,64 @@
// 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
#include "executable_semantics/ast/declaration.h"
#include <iostream>
namespace Carbon {
auto MakeFunDecl(FunctionDefinition* f) -> Declaration* {
auto* d = new Declaration();
d->tag = DeclarationKind::FunctionDeclaration;
d->u.fun_def = f;
return d;
}
auto MakeStructDecl(int line_num, std::string name, std::list<Member*>* members)
-> Declaration* {
auto* d = new Declaration();
d->tag = DeclarationKind::StructDeclaration;
d->u.struct_def = new StructDefinition();
d->u.struct_def->line_num = line_num;
d->u.struct_def->name = new std::string(std::move(name));
d->u.struct_def->members = members;
return d;
}
auto MakeChoiceDecl(int line_num, std::string name,
std::list<std::pair<std::string, Expression*>>* alts)
-> Declaration* {
auto* d = new Declaration();
d->tag = DeclarationKind::ChoiceDeclaration;
d->u.choice_def.line_num = line_num;
d->u.choice_def.name = new std::string(std::move(name));
d->u.choice_def.alternatives = alts;
return d;
}
void PrintDecl(Declaration* d) {
switch (d->tag) {
case DeclarationKind::FunctionDeclaration:
PrintFunDef(d->u.fun_def);
break;
case DeclarationKind::StructDeclaration:
std::cout << "struct " << *d->u.struct_def->name << " {" << std::endl;
for (auto& member : *d->u.struct_def->members) {
PrintMember(member);
}
std::cout << "}" << std::endl;
break;
case DeclarationKind::ChoiceDeclaration:
std::cout << "choice " << *d->u.choice_def.name << " {" << std::endl;
for (auto& alternative : *d->u.choice_def.alternatives) {
std::cout << "alt " << alternative.first << " ";
PrintExp(alternative.second);
std::cout << ";" << std::endl;
}
std::cout << "}" << std::endl;
break;
}
}
} // namespace Carbon
+47
View File
@@ -0,0 +1,47 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
#define EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
#include <list>
#include <string>
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/ast/member.h"
#include "executable_semantics/ast/struct_definition.h"
namespace Carbon {
enum class DeclarationKind {
FunctionDeclaration,
StructDeclaration,
ChoiceDeclaration
};
struct Declaration {
DeclarationKind tag;
union {
struct FunctionDefinition* fun_def;
struct StructDefinition* struct_def;
struct {
int line_num;
std::string* name;
std::list<std::pair<std::string, Expression*>>* alternatives;
} choice_def;
} u;
};
auto MakeFunDecl(struct FunctionDefinition* f) -> Declaration*;
auto MakeStructDecl(int line_num, std::string name, std::list<Member*>* members)
-> Declaration*;
auto MakeChoiceDecl(int line_num, std::string name,
std::list<std::pair<std::string, Expression*>>* alts)
-> Declaration*;
void PrintDecl(Declaration* d);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
+284
View File
@@ -0,0 +1,284 @@
// 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
#include "executable_semantics/ast/expression.h"
#include <iostream>
namespace Carbon {
auto MakeTypeType(int line_num) -> Expression* {
auto* t = new Expression();
t->tag = ExpressionKind::TypeT;
t->line_num = line_num;
return t;
}
auto MakeIntType(int line_num) -> Expression* {
auto* t = new Expression();
t->tag = ExpressionKind::IntT;
t->line_num = line_num;
return t;
}
auto MakeBoolType(int line_num) -> Expression* {
auto* t = new Expression();
t->tag = ExpressionKind::BoolT;
t->line_num = line_num;
return t;
}
auto MakeAutoType(int line_num) -> Expression* {
auto* t = new Expression();
t->tag = ExpressionKind::AutoT;
t->line_num = line_num;
return t;
}
auto MakeFunType(int line_num, Expression* param, Expression* ret)
-> Expression* {
auto* t = new Expression();
t->tag = ExpressionKind::FunctionT;
t->line_num = line_num;
t->u.function_type.parameter = param;
t->u.function_type.return_type = ret;
return t;
}
auto MakeVar(int line_num, std::string var) -> Expression* {
auto* v = new Expression();
v->line_num = line_num;
v->tag = ExpressionKind::Variable;
v->u.variable.name = new std::string(std::move(var));
return v;
}
auto MakeVarPat(int line_num, std::string var, Expression* type)
-> Expression* {
auto* v = new Expression();
v->line_num = line_num;
v->tag = ExpressionKind::PatternVariable;
v->u.pattern_variable.name = new std::string(std::move(var));
v->u.pattern_variable.type = type;
return v;
}
auto MakeInt(int line_num, int i) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::Integer;
e->u.integer = i;
return e;
}
auto MakeBool(int line_num, bool b) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::Boolean;
e->u.boolean = b;
return e;
}
auto MakeOp(int line_num, enum Operator op, std::vector<Expression*>* args)
-> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::PrimitiveOp;
e->u.primitive_op.op = op;
e->u.primitive_op.arguments = args;
return e;
}
auto MakeUnOp(int line_num, enum Operator op, Expression* arg) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::PrimitiveOp;
e->u.primitive_op.op = op;
auto* args = new std::vector<Expression*>();
args->push_back(arg);
e->u.primitive_op.arguments = args;
return e;
}
auto MakeBinOp(int line_num, enum Operator op, Expression* arg1,
Expression* arg2) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::PrimitiveOp;
e->u.primitive_op.op = op;
auto* args = new std::vector<Expression*>();
args->push_back(arg1);
args->push_back(arg2);
e->u.primitive_op.arguments = args;
return e;
}
auto MakeCall(int line_num, Expression* fun, Expression* arg) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::Call;
e->u.call.function = fun;
e->u.call.argument = arg;
return e;
}
auto MakeGetField(int line_num, Expression* exp, std::string field)
-> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::GetField;
e->u.get_field.aggregate = exp;
e->u.get_field.field = new std::string(std::move(field));
return e;
}
auto MakeTuple(int line_num,
std::vector<std::pair<std::string, Expression*>>* args)
-> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::Tuple;
int i = 0;
for (auto& arg : *args) {
if (arg.first == "") {
arg.first = std::to_string(i);
++i;
}
}
e->u.tuple.fields = args;
return e;
}
auto MakeIndex(int line_num, Expression* exp, Expression* i) -> Expression* {
auto* e = new Expression();
e->line_num = line_num;
e->tag = ExpressionKind::Index;
e->u.index.aggregate = exp;
e->u.index.offset = i;
return e;
}
static void PrintOp(Operator op) {
switch (op) {
case Operator::Neg:
std::cout << "-";
break;
case Operator::Add:
std::cout << "+";
break;
case Operator::Sub:
std::cout << "-";
break;
case Operator::Not:
std::cout << "!";
break;
case Operator::And:
std::cout << "&&";
break;
case Operator::Or:
std::cout << "||";
break;
case Operator::Eq:
std::cout << "==";
break;
}
}
static void PrintFields(
std::vector<std::pair<std::string, Expression*>>* fields) {
int i = 0;
for (auto iter = fields->begin(); iter != fields->end(); ++iter, ++i) {
if (i != 0) {
std::cout << ", ";
}
std::cout << iter->first << " = ";
PrintExp(iter->second);
}
}
void PrintExp(Expression* e) {
switch (e->tag) {
case ExpressionKind::Index:
PrintExp(e->u.index.aggregate);
std::cout << "[";
PrintExp(e->u.index.offset);
std::cout << "]";
break;
case ExpressionKind::GetField:
PrintExp(e->u.get_field.aggregate);
std::cout << ".";
std::cout << *e->u.get_field.field;
break;
case ExpressionKind::Tuple:
std::cout << "(";
PrintFields(e->u.tuple.fields);
std::cout << ")";
break;
case ExpressionKind::Integer:
std::cout << e->u.integer;
break;
case ExpressionKind::Boolean:
std::cout << std::boolalpha;
std::cout << e->u.boolean;
break;
case ExpressionKind::PrimitiveOp:
std::cout << "(";
if (e->u.primitive_op.arguments->size() == 0) {
PrintOp(e->u.primitive_op.op);
} else if (e->u.primitive_op.arguments->size() == 1) {
PrintOp(e->u.primitive_op.op);
std::cout << " ";
auto iter = e->u.primitive_op.arguments->begin();
PrintExp(*iter);
} else if (e->u.primitive_op.arguments->size() == 2) {
auto iter = e->u.primitive_op.arguments->begin();
PrintExp(*iter);
std::cout << " ";
PrintOp(e->u.primitive_op.op);
std::cout << " ";
++iter;
PrintExp(*iter);
}
std::cout << ")";
break;
case ExpressionKind::Variable:
std::cout << *e->u.variable.name;
break;
case ExpressionKind::PatternVariable:
PrintExp(e->u.pattern_variable.type);
std::cout << ": ";
std::cout << *e->u.pattern_variable.name;
break;
case ExpressionKind::Call:
PrintExp(e->u.call.function);
if (e->u.call.argument->tag == ExpressionKind::Tuple) {
PrintExp(e->u.call.argument);
} else {
std::cout << "(";
PrintExp(e->u.call.argument);
std::cout << ")";
}
break;
case ExpressionKind::BoolT:
std::cout << "Bool";
break;
case ExpressionKind::IntT:
std::cout << "Int";
break;
case ExpressionKind::TypeT:
std::cout << "Type";
break;
case ExpressionKind::AutoT:
std::cout << "auto";
break;
case ExpressionKind::FunctionT:
std::cout << "fn ";
PrintExp(e->u.function_type.parameter);
std::cout << " -> ";
PrintExp(e->u.function_type.return_type);
break;
}
}
} // namespace Carbon
+106
View File
@@ -0,0 +1,106 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
#define EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
#include <string>
#include <vector>
namespace Carbon {
enum class ExpressionKind {
AutoT,
BoolT,
Boolean,
Call,
FunctionT,
GetField,
Index,
IntT,
Integer,
PatternVariable,
PrimitiveOp,
Tuple,
TypeT,
Variable,
};
enum class Operator {
Add,
And,
Eq,
Neg,
Not,
Or,
Sub,
};
struct Expression {
int line_num;
ExpressionKind tag;
union {
struct {
std::string* name;
} variable;
struct {
Expression* aggregate;
std::string* field;
} get_field;
struct {
Expression* aggregate;
Expression* offset;
} index;
struct {
std::string* name;
Expression* type;
} pattern_variable;
int integer;
bool boolean;
struct {
std::vector<std::pair<std::string, Expression*>>* fields;
} tuple;
struct {
Operator op;
std::vector<Expression*>* arguments;
} primitive_op;
struct {
Expression* function;
Expression* argument;
} call;
struct {
Expression* parameter;
Expression* return_type;
} function_type;
} u;
};
auto MakeVar(int line_num, std::string var) -> Expression*;
auto MakeVarPat(int line_num, std::string var, Expression* type) -> Expression*;
auto MakeInt(int line_num, int i) -> Expression*;
auto MakeBool(int line_num, bool b) -> Expression*;
auto MakeOp(int line_num, Operator op, std::vector<Expression*>* args)
-> Expression*;
auto MakeUnOp(int line_num, enum Operator op, Expression* arg) -> Expression*;
auto MakeBinOp(int line_num, enum Operator op, Expression* arg1,
Expression* arg2) -> Expression*;
auto MakeCall(int line_num, Expression* fun, Expression* arg) -> Expression*;
auto MakeGetField(int line_num, Expression* exp, std::string field)
-> Expression*;
auto MakeTuple(int line_num,
std::vector<std::pair<std::string, Expression*>>* args)
-> Expression*;
auto MakeIndex(int line_num, Expression* exp, Expression* i) -> Expression*;
auto MakeTypeType(int line_num) -> Expression*;
auto MakeIntType(int line_num) -> Expression*;
auto MakeBoolType(int line_num) -> Expression*;
auto MakeFunType(int line_num, Expression* param, Expression* ret)
-> Expression*;
auto MakeAutoType(int line_num) -> Expression*;
void PrintExp(Expression* exp);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
@@ -0,0 +1,49 @@
// 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
#include "executable_semantics/ast/expression_or_field_list.h"
namespace Carbon {
auto MakeExp(Expression* exp) -> ExpOrFieldList* {
auto e = new ExpOrFieldList();
e->tag = ExpOrFieldListKind::Exp;
e->u.exp = exp;
return e;
}
auto MakeFieldList(std::list<std::pair<std::string, Expression*>>* fields)
-> ExpOrFieldList* {
auto e = new ExpOrFieldList();
e->tag = ExpOrFieldListKind::FieldList;
e->u.fields = fields;
return e;
}
auto MakeConsField(ExpOrFieldList* e1, ExpOrFieldList* e2) -> ExpOrFieldList* {
auto fields = new std::list<std::pair<std::string, Expression*>>();
switch (e1->tag) {
case ExpOrFieldListKind::Exp:
fields->push_back(std::make_pair("", e1->u.exp));
break;
case ExpOrFieldListKind::FieldList:
for (auto& field : *e1->u.fields) {
fields->push_back(field);
}
break;
}
switch (e2->tag) {
case ExpOrFieldListKind::Exp:
fields->push_back(std::make_pair("", e2->u.exp));
break;
case ExpOrFieldListKind::FieldList:
for (auto& field : *e2->u.fields) {
fields->push_back(field);
}
break;
}
return MakeFieldList(fields);
}
} // namespace Carbon
@@ -0,0 +1,32 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_EXPRESSION_OR_FIELD_LIST_H_
#define EXECUTABLE_SEMANTICS_AST_EXPRESSION_OR_FIELD_LIST_H_
#include <list>
#include "executable_semantics/ast/expression.h"
namespace Carbon {
enum class ExpOrFieldListKind { Exp, FieldList };
// This is used in the parsing of tuples and parenthesized expressions.
struct ExpOrFieldList {
ExpOrFieldListKind tag;
union {
Expression* exp;
std::list<std::pair<std::string, Expression*>>* fields;
} u;
};
auto MakeExp(Expression* exp) -> ExpOrFieldList*;
auto MakeFieldList(std::list<std::pair<std::string, Expression*>>* fields)
-> ExpOrFieldList*;
auto MakeConsField(ExpOrFieldList* e1, ExpOrFieldList* e2) -> ExpOrFieldList*;
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_OR_FIELD_LIST_H_
@@ -0,0 +1,39 @@
// 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
#include "executable_semantics/ast/function_definition.h"
#include <iostream>
namespace Carbon {
auto MakeFunDef(int line_num, std::string name, Expression* ret_type,
Expression* param_pattern, Statement* body)
-> struct FunctionDefinition* {
auto* f = new struct FunctionDefinition();
f->line_num = line_num;
f->name = std::move(name);
f->return_type = ret_type;
f->param_pattern = param_pattern;
f->body = body;
return f;
}
void PrintFunDefDepth(struct FunctionDefinition* f, int depth) {
std::cout << "fn " << f->name << " ";
PrintExp(f->param_pattern);
std::cout << " -> ";
PrintExp(f->return_type);
if (f->body) {
std::cout << " {" << std::endl;
PrintStatement(f->body, depth);
std::cout << std::endl << "}" << std::endl;
} else {
std::cout << ";" << std::endl;
}
}
void PrintFunDef(struct FunctionDefinition* f) { PrintFunDefDepth(f, -1); }
} // namespace Carbon
@@ -0,0 +1,29 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_FUNCTION_DEFINITION_H_
#define EXECUTABLE_SEMANTICS_AST_FUNCTION_DEFINITION_H_
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/statement.h"
namespace Carbon {
struct FunctionDefinition {
int line_num;
std::string name;
Expression* param_pattern;
Expression* return_type;
Statement* body;
};
auto MakeFunDef(int line_num, std::string name, Expression* ret_type,
Expression* param, Statement* body)
-> struct FunctionDefinition*;
void PrintFunDef(struct FunctionDefinition*);
void PrintFunDefDepth(struct FunctionDefinition*, int);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_FUNCTION_DEFINITION_H_
+30
View File
@@ -0,0 +1,30 @@
// 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
#include "executable_semantics/ast/member.h"
#include <iostream>
namespace Carbon {
auto MakeField(int line_num, std::string name, Expression* type) -> Member* {
auto m = new Member();
m->line_num = line_num;
m->tag = MemberKind::FieldMember;
m->u.field.name = new std::string(std::move(name));
m->u.field.type = type;
return m;
}
void PrintMember(Member* m) {
switch (m->tag) {
case MemberKind::FieldMember:
std::cout << "var " << *m->u.field.name << " : ";
PrintExp(m->u.field.type);
std::cout << ";" << std::endl;
break;
}
}
} // namespace Carbon
+33
View File
@@ -0,0 +1,33 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_MEMBER_H_
#define EXECUTABLE_SEMANTICS_AST_MEMBER_H_
#include <string>
#include "executable_semantics/ast/expression.h"
namespace Carbon {
enum class MemberKind { FieldMember };
struct Member {
int line_num;
MemberKind tag;
union {
struct {
std::string* name;
Expression* type;
} field;
} u;
};
auto MakeField(int line_num, std::string name, Expression* type) -> Member*;
void PrintMember(Member* m);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_MEMBER_H_
+190
View File
@@ -0,0 +1,190 @@
// 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
#include "executable_semantics/ast/statement.h"
#include <iostream>
namespace Carbon {
auto MakeExpStmt(int line_num, Expression* exp) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::ExpressionStatement;
s->u.exp = exp;
return s;
}
auto MakeAssign(int line_num, Expression* lhs, Expression* rhs) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Assign;
s->u.assign.lhs = lhs;
s->u.assign.rhs = rhs;
return s;
}
auto MakeVarDef(int line_num, Expression* pat, Expression* init) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::VariableDefinition;
s->u.variable_definition.pat = pat;
s->u.variable_definition.init = init;
return s;
}
auto MakeIf(int line_num, Expression* cond, Statement* then_stmt,
Statement* else_stmt) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::If;
s->u.if_stmt.cond = cond;
s->u.if_stmt.then_stmt = then_stmt;
s->u.if_stmt.else_stmt = else_stmt;
return s;
}
auto MakeWhile(int line_num, Expression* cond, Statement* body) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::While;
s->u.while_stmt.cond = cond;
s->u.while_stmt.body = body;
return s;
}
auto MakeBreak(int line_num) -> Statement* {
std::cout << "MakeBlock" << std::endl;
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Break;
return s;
}
auto MakeContinue(int line_num) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Continue;
return s;
}
auto MakeReturn(int line_num, Expression* e) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Return;
s->u.return_stmt = e;
return s;
}
auto MakeSeq(int line_num, Statement* s1, Statement* s2) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Sequence;
s->u.sequence.stmt = s1;
s->u.sequence.next = s2;
return s;
}
auto MakeBlock(int line_num, Statement* stmt) -> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Block;
s->u.block.stmt = stmt;
return s;
}
auto MakeMatch(int line_num, Expression* exp,
std::list<std::pair<Expression*, Statement*>>* clauses)
-> Statement* {
auto* s = new Statement();
s->line_num = line_num;
s->tag = StatementKind::Match;
s->u.match_stmt.exp = exp;
s->u.match_stmt.clauses = clauses;
return s;
}
void PrintStatement(Statement* s, int depth) {
if (!s) {
return;
}
if (depth == 0) {
std::cout << " ... ";
return;
}
switch (s->tag) {
case StatementKind::Match:
std::cout << "match (";
PrintExp(s->u.match_stmt.exp);
std::cout << ") {";
if (depth < 0 || depth > 1) {
std::cout << std::endl;
for (auto& clause : *s->u.match_stmt.clauses) {
std::cout << "case ";
PrintExp(clause.first);
std::cout << " =>" << std::endl;
PrintStatement(clause.second, depth - 1);
std::cout << std::endl;
}
} else {
std::cout << "...";
}
std::cout << "}";
break;
case StatementKind::While:
std::cout << "while (";
PrintExp(s->u.while_stmt.cond);
std::cout << ")" << std::endl;
PrintStatement(s->u.while_stmt.body, depth - 1);
break;
case StatementKind::Break:
std::cout << "break;";
break;
case StatementKind::Continue:
std::cout << "continue;";
break;
case StatementKind::VariableDefinition:
std::cout << "var ";
PrintExp(s->u.variable_definition.pat);
std::cout << " = ";
PrintExp(s->u.variable_definition.init);
std::cout << ";";
break;
case StatementKind::ExpressionStatement:
PrintExp(s->u.exp);
std::cout << ";";
break;
case StatementKind::Assign:
PrintExp(s->u.assign.lhs);
std::cout << " = ";
PrintExp(s->u.assign.rhs);
std::cout << ";";
break;
case StatementKind::If:
std::cout << "if (";
PrintExp(s->u.if_stmt.cond);
std::cout << ")" << std::endl;
PrintStatement(s->u.if_stmt.then_stmt, depth - 1);
std::cout << std::endl << "else" << std::endl;
PrintStatement(s->u.if_stmt.else_stmt, depth - 1);
break;
case StatementKind::Return:
std::cout << "return ";
PrintExp(s->u.return_stmt);
std::cout << ";";
break;
case StatementKind::Sequence:
PrintStatement(s->u.sequence.stmt, depth);
if (depth < 0 || depth > 1) {
std::cout << std::endl;
}
PrintStatement(s->u.sequence.next, depth - 1);
break;
case StatementKind::Block:
std::cout << "{" << std::endl;
PrintStatement(s->u.block.stmt, depth - 1);
std::cout << std::endl << "}" << std::endl;
}
}
} // namespace Carbon
+84
View File
@@ -0,0 +1,84 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_STATEMENT_H_
#define EXECUTABLE_SEMANTICS_AST_STATEMENT_H_
#include <list>
#include "executable_semantics/ast/expression.h"
namespace Carbon {
enum class StatementKind {
ExpressionStatement,
Assign,
VariableDefinition,
If,
Return,
Sequence,
Block,
While,
Break,
Continue,
Match
};
struct Statement {
int line_num;
StatementKind tag;
union {
Expression* exp;
struct {
Expression* lhs;
Expression* rhs;
} assign;
struct {
Expression* pat;
Expression* init;
} variable_definition;
struct {
Expression* cond;
Statement* then_stmt;
Statement* else_stmt;
} if_stmt;
Expression* return_stmt;
struct {
Statement* stmt;
Statement* next;
} sequence;
struct {
Statement* stmt;
} block;
struct {
Expression* cond;
Statement* body;
} while_stmt;
struct {
Expression* exp;
std::list<std::pair<Expression*, Statement*>>* clauses;
} match_stmt;
} u;
};
auto MakeExpStmt(int line_num, Expression* exp) -> Statement*;
auto MakeAssign(int line_num, Expression* lhs, Expression* rhs) -> Statement*;
auto MakeVarDef(int line_num, Expression* pat, Expression* init) -> Statement*;
auto MakeIf(int line_num, Expression* cond, Statement* then_stmt,
Statement* else_stmt) -> Statement*;
auto MakeReturn(int line_num, Expression* e) -> Statement*;
auto MakeSeq(int line_num, Statement* s1, Statement* s2) -> Statement*;
auto MakeBlock(int line_num, Statement* s) -> Statement*;
auto MakeWhile(int line_num, Expression* cond, Statement* body) -> Statement*;
auto MakeBreak(int line_num) -> Statement*;
auto MakeContinue(int line_num) -> Statement*;
auto MakeMatch(int line_num, Expression* exp,
std::list<std::pair<Expression*, Statement*>>* clauses)
-> Statement*;
void PrintStatement(Statement*, int);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_STATEMENT_H_
@@ -0,0 +1,23 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_AST_STRUCT_DEFINITION_H_
#define EXECUTABLE_SEMANTICS_AST_STRUCT_DEFINITION_H_
#include <list>
#include <string>
#include "executable_semantics/ast/member.h"
namespace Carbon {
struct StructDefinition {
int line_num;
std::string* name;
std::list<Member*>* members;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_STRUCT_DEFINITION_H_
+33
View File
@@ -0,0 +1,33 @@
# 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
load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//executable_semantics:__subpackages__"])
# TODO: It may be helpful to break this apart.
cc_library(
name = "interpreter",
srcs = [
"action.cpp",
"interpreter.cpp",
"typecheck.cpp",
"value.cpp",
],
hdrs = [
"action.h",
"assoc_list.h",
"cons_list.h",
"interpreter.h",
"typecheck.h",
"value.h",
],
deps = [
"//executable_semantics/ast:declaration",
"//executable_semantics/ast:expression",
"//executable_semantics/ast:function_definition",
"//executable_semantics/ast:member",
"//executable_semantics/ast:statement",
],
)
+108
View File
@@ -0,0 +1,108 @@
// 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
#include <iostream>
#include <iterator>
#include <map>
#include <optional>
#include <utility>
#include <vector>
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/interpreter/interpreter.h"
#include "executable_semantics/interpreter/typecheck.h"
namespace Carbon {
void PrintAct(Action* act, std::ostream& out) {
switch (act->tag) {
case ActionKind::DeleteTmpAction:
std::cout << "delete_tmp(" << act->u.delete_tmp << ")";
break;
case ActionKind::ExpToLValAction:
out << "exp=>lval";
break;
case ActionKind::LValAction:
case ActionKind::ExpressionAction:
PrintExp(act->u.exp);
break;
case ActionKind::StatementAction:
PrintStatement(act->u.stmt, 1);
break;
case ActionKind::ValAction:
PrintValue(act->u.val, out);
break;
}
out << "<" << act->pos << ">";
if (act->results.size() > 0) {
out << "(";
for (auto& result : act->results) {
if (result) {
PrintValue(result, out);
}
out << ",";
}
out << ")";
}
}
void PrintActList(Cons<Action*>* ls, std::ostream& out) {
if (ls) {
PrintAct(ls->curr, out);
if (ls->next) {
out << " :: ";
PrintActList(ls->next, out);
}
}
}
auto MakeExpAct(Expression* e) -> Action* {
auto* act = new Action();
act->tag = ActionKind::ExpressionAction;
act->u.exp = e;
act->pos = -1;
return act;
}
auto MakeLvalAct(Expression* e) -> Action* {
auto* act = new Action();
act->tag = ActionKind::LValAction;
act->u.exp = e;
act->pos = -1;
return act;
}
auto MakeStmtAct(Statement* s) -> Action* {
auto* act = new Action();
act->tag = ActionKind::StatementAction;
act->u.stmt = s;
act->pos = -1;
return act;
}
auto MakeValAct(Value* v) -> Action* {
auto* act = new Action();
act->tag = ActionKind::ValAction;
act->u.val = v;
act->pos = -1;
return act;
}
auto MakeExpToLvalAct() -> Action* {
auto* act = new Action();
act->tag = ActionKind::ExpToLValAction;
act->pos = -1;
return act;
}
auto MakeDeleteAct(Address a) -> Action* {
auto* act = new Action();
act->tag = ActionKind::DeleteTmpAction;
act->pos = -1;
act->u.delete_tmp = a;
return act;
}
} // namespace Carbon
+50
View File
@@ -0,0 +1,50 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_ACTION_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_ACTION_H_
#include <iostream>
#include <vector>
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/statement.h"
#include "executable_semantics/interpreter/cons_list.h"
#include "executable_semantics/interpreter/value.h"
namespace Carbon {
enum class ActionKind {
LValAction,
ExpressionAction,
StatementAction,
ValAction,
ExpToLValAction,
DeleteTmpAction
};
struct Action {
ActionKind tag;
union {
Expression* exp; // for LValAction and ExpressionAction
Statement* stmt;
Value* val; // for finished actions with a value (ValAction)
Address delete_tmp;
} u;
int pos; // position or state of the action
std::vector<Value*> results; // results from subexpression
};
void PrintAct(Action* act, std::ostream& out);
void PrintActList(Cons<Action*>* ls, std::ostream& out);
auto MakeExpAct(Expression* e) -> Action*;
auto MakeLvalAct(Expression* e) -> Action*;
auto MakeStmtAct(Statement* s) -> Action*;
auto MakeValAct(Value* v) -> Action*;
auto MakeExpToLvalAct() -> Action*;
auto MakeDeleteAct(Address a) -> Action*;
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_ACTION_H_
@@ -0,0 +1,38 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_ASSOC_LIST_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_ASSOC_LIST_H_
#include <iostream>
#include <list>
#include <string>
namespace Carbon {
template <class K, class V>
struct AssocList {
AssocList(K k, V v, AssocList* n) : key(k), value(v), next(n) {}
K key;
V value;
AssocList* next;
};
template <class K, class V>
auto Lookup(int line_num, AssocList<K, V>* alist, const K& key,
void (*print_key)(const K&)) -> V {
if (alist == NULL) {
std::cerr << line_num << ": could not find `" << key << "`" << std::endl;
exit(-1);
} else if (alist->key == key) {
return alist->value;
} else {
return Lookup(line_num, alist->next, key, print_key);
}
}
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_ASSOC_LIST_H_
@@ -0,0 +1,39 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_CONS_LIST_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_CONS_LIST_H_
namespace Carbon {
template <class T>
struct Cons {
Cons(T e, Cons* n) : curr(e), next(n) {}
T curr;
Cons* next;
};
template <class T>
auto MakeCons(const T& x) -> Cons<T>* {
return new Cons<T>(x, nullptr);
}
template <class T>
auto MakeCons(const T& x, Cons<T>* ls) -> Cons<T>* {
return new Cons<T>(x, ls);
}
template <class T>
auto Length(Cons<T>* ls) -> unsigned int {
if (ls) {
return 1 + Length(ls->next);
} else {
return 0;
}
}
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_CONS_LIST_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,60 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_INTERPRETER_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_INTERPRETER_H_
#include <list>
#include <utility>
#include <vector>
#include "executable_semantics/ast/declaration.h"
#include "executable_semantics/interpreter/action.h"
#include "executable_semantics/interpreter/assoc_list.h"
#include "executable_semantics/interpreter/cons_list.h"
#include "executable_semantics/interpreter/value.h"
namespace Carbon {
using Env = AssocList<std::string, Address>;
/***** Scopes *****/
struct Scope {
Scope(Env* e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
Env* env;
std::list<std::string> locals;
};
/***** Frames and State *****/
struct Frame {
std::string name;
Cons<Scope*>* scopes;
Cons<Action*>* todo;
Frame(std::string n, Cons<Scope*>* s, Cons<Action*>* c)
: name(std::move(std::move(n))), scopes(s), todo(c) {}
};
struct State {
Cons<Frame*>* stack;
std::vector<Value*> heap;
};
extern State* state;
void PrintEnv(Env* env);
auto AllocateValue(Value* v) -> Address;
auto CopyVal(Value* val, int line_num) -> Value*;
auto ToInteger(Value* v) -> int;
/***** Interpreters *****/
auto InterpProgram(std::list<Declaration*>* fs) -> int;
auto InterpExp(Env* env, Expression* e) -> Value*;
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_INTERPRETER_H_
@@ -0,0 +1,680 @@
// 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
#include "executable_semantics/interpreter/typecheck.h"
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/interpreter/cons_list.h"
#include "executable_semantics/interpreter/interpreter.h"
namespace Carbon {
auto Find(const std::string& s, Cons<std::string>* ls, int n) -> int {
if (ls) {
if (ls->curr == s) {
return n;
} else {
return Find(s, ls->next, n + 1);
}
} else {
std::cerr << "could not find " << s << std::endl;
exit(-1);
}
}
void ExpectType(int line_num, const std::string& context, Value* expected,
Value* actual) {
if (!TypeEqual(expected, actual)) {
std::cerr << line_num << ": type error in " << context << std::endl;
std::cerr << "expected: ";
PrintValue(expected, std::cerr);
std::cerr << std::endl << "actual: ";
PrintValue(actual, std::cerr);
std::cerr << std::endl;
exit(-1);
}
}
void PrintErrorString(const std::string& s) { std::cerr << s; }
void PrintTypeEnv(TypeEnv* env, std::ostream& out) {
if (env) {
out << env->key << ": ";
PrintValue(env->value, out);
out << ", ";
PrintTypeEnv(env->next, out);
}
}
// Convert tuples to tuple types.
auto ToType(int line_num, Value* val) -> Value* {
switch (val->tag) {
case ValKind::TupleV: {
auto fields = new VarValues();
for (auto& elt : *val->u.tuple.elts) {
Value* ty = ToType(line_num, state->heap[elt.second]);
fields->push_back(std::make_pair(elt.first, ty));
}
return MakeTupleTypeVal(fields);
}
case ValKind::TupleTV: {
auto fields = new VarValues();
for (auto& field : *val->u.tuple_type.fields) {
Value* ty = ToType(line_num, field.second);
fields->push_back(std::make_pair(field.first, ty));
}
return MakeTupleTypeVal(fields);
}
case ValKind::PointerTV: {
return MakePtrTypeVal(ToType(line_num, val->u.ptr_type.type));
}
case ValKind::FunctionTV: {
return MakeFunTypeVal(ToType(line_num, val->u.fun_type.param),
ToType(line_num, val->u.fun_type.ret));
}
case ValKind::VarPatV: {
return MakeVarPatVal(*val->u.var_pat.name,
ToType(line_num, val->u.var_pat.type));
}
case ValKind::ChoiceTV:
case ValKind::StructTV:
case ValKind::TypeTV:
case ValKind::VarTV:
case ValKind::BoolTV:
case ValKind::IntTV:
case ValKind::AutoTV:
return val;
default:
std::cerr << line_num << ": in ToType, expected a type, not ";
PrintValue(val, std::cerr);
std::cerr << std::endl;
exit(-1);
}
}
// Reify type to type expression.
auto ReifyType(Value* t, int line_num) -> Expression* {
switch (t->tag) {
case ValKind::VarTV:
return MakeVar(0, *t->u.var_type);
case ValKind::IntTV:
return MakeIntType(0);
case ValKind::BoolTV:
return MakeBoolType(0);
case ValKind::TypeTV:
return MakeTypeType(0);
case ValKind::FunctionTV:
return MakeFunType(0, ReifyType(t->u.fun_type.param, line_num),
ReifyType(t->u.fun_type.ret, line_num));
case ValKind::TupleTV: {
auto args = new std::vector<std::pair<std::string, Expression*>>();
for (auto& field : *t->u.tuple_type.fields) {
args->push_back(
make_pair(field.first, ReifyType(field.second, line_num)));
}
return MakeTuple(0, args);
}
case ValKind::StructTV:
return MakeVar(0, *t->u.struct_type.name);
case ValKind::ChoiceTV:
return MakeVar(0, *t->u.choice_type.name);
default:
std::cerr << line_num << ": expected a type, not ";
PrintValue(t, std::cerr);
std::cerr << std::endl;
exit(-1);
}
}
auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
TCContext context)
-> TCResult { // expected can be null
switch (e->tag) {
case ExpressionKind::PatternVariable: {
if (context != TCContext::PatternContext) {
std::cerr
<< e->line_num
<< ": compilation error, pattern variables are only allowed in "
"pattern context"
<< std::endl;
}
auto t =
ToType(e->line_num, InterpExp(ct_env, e->u.pattern_variable.type));
if (t->tag == ValKind::AutoTV) {
if (expected == nullptr) {
std::cerr << e->line_num
<< ": compilation error, auto not allowed here"
<< std::endl;
exit(-1);
} else {
t = expected;
}
}
auto new_e = MakeVarPat(e->line_num, *e->u.pattern_variable.name,
ReifyType(t, e->line_num));
return TCResult(new_e, t,
new TypeEnv(*e->u.pattern_variable.name, t, env));
}
case ExpressionKind::Index: {
auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
TCContext::ValueContext);
auto t = res.type;
switch (t->tag) {
case ValKind::TupleTV: {
auto i = ToInteger(InterpExp(ct_env, e->u.index.offset));
std::string f = std::to_string(i);
auto field_t = FindInVarValues(f, t->u.tuple_type.fields);
if (field_t == nullptr) {
std::cerr << e->line_num << ": compilation error, field " << f
<< " is not in the tuple ";
PrintValue(t, std::cerr);
std::cerr << std::endl;
exit(-1);
}
auto new_e = MakeIndex(e->line_num, res.exp, MakeInt(e->line_num, i));
return TCResult(new_e, field_t, res.env);
}
default:
std::cerr << e->line_num << ": compilation error, expected a tuple"
<< std::endl;
exit(-1);
}
}
case ExpressionKind::Tuple: {
auto new_args = new std::vector<std::pair<std::string, Expression*>>();
auto arg_types = new VarValues();
auto new_env = env;
int i = 0;
for (auto arg = e->u.tuple.fields->begin();
arg != e->u.tuple.fields->end(); ++arg, ++i) {
Value* arg_expected = nullptr;
if (expected && expected->tag == ValKind::TupleTV) {
arg_expected =
FindInVarValues(arg->first, expected->u.tuple_type.fields);
if (arg_expected == nullptr) {
std::cerr << e->line_num << ": compilation error, missing field "
<< arg->first << std::endl;
exit(-1);
}
}
auto arg_res =
TypeCheckExp(arg->second, new_env, ct_env, arg_expected, context);
new_env = arg_res.env;
new_args->push_back(std::make_pair(arg->first, arg_res.exp));
arg_types->push_back(std::make_pair(arg->first, arg_res.type));
}
auto tuple_e = MakeTuple(e->line_num, new_args);
auto tuple_t = MakeTupleTypeVal(arg_types);
return TCResult(tuple_e, tuple_t, new_env);
}
case ExpressionKind::GetField: {
auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
TCContext::ValueContext);
auto t = res.type;
switch (t->tag) {
case ValKind::StructTV:
// Search for a field
for (auto& field : *t->u.struct_type.fields) {
if (*e->u.get_field.field == field.first) {
Expression* new_e =
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
return TCResult(new_e, field.second, res.env);
}
}
// Search for a method
for (auto& method : *t->u.struct_type.methods) {
if (*e->u.get_field.field == method.first) {
Expression* new_e =
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
return TCResult(new_e, method.second, res.env);
}
}
std::cerr << e->line_num << ": compilation error, struct "
<< *t->u.struct_type.name << " does not have a field named "
<< *e->u.get_field.field << std::endl;
exit(-1);
case ValKind::TupleTV:
for (auto& field : *t->u.tuple_type.fields) {
if (*e->u.get_field.field == field.first) {
auto new_e =
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
return TCResult(new_e, field.second, res.env);
}
}
std::cerr << e->line_num << ": compilation error, struct "
<< *t->u.struct_type.name << " does not have a field named "
<< *e->u.get_field.field << std::endl;
exit(-1);
case ValKind::ChoiceTV:
for (auto vt = t->u.choice_type.alternatives->begin();
vt != t->u.choice_type.alternatives->end(); ++vt) {
if (*e->u.get_field.field == vt->first) {
Expression* new_e =
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
auto fun_ty = MakeFunTypeVal(vt->second, t);
return TCResult(new_e, fun_ty, res.env);
}
}
std::cerr << e->line_num << ": compilation error, struct "
<< *t->u.struct_type.name << " does not have a field named "
<< *e->u.get_field.field << std::endl;
exit(-1);
default:
std::cerr << e->line_num
<< ": compilation error in field access, expected a struct"
<< std::endl;
PrintExp(e);
std::cerr << std::endl;
exit(-1);
}
}
case ExpressionKind::Variable: {
auto t =
Lookup(e->line_num, env, *(e->u.variable.name), PrintErrorString);
return TCResult(e, t, env);
}
case ExpressionKind::Integer:
return TCResult(e, MakeIntTypeVal(), env);
case ExpressionKind::Boolean:
return TCResult(e, MakeBoolTypeVal(), env);
case ExpressionKind::PrimitiveOp: {
auto es = new std::vector<Expression*>();
std::vector<Value*> ts;
auto new_env = env;
for (auto& argument : *e->u.primitive_op.arguments) {
auto res = TypeCheckExp(argument, env, ct_env, nullptr,
TCContext::ValueContext);
new_env = res.env;
es->push_back(res.exp);
ts.push_back(res.type);
}
auto new_e = MakeOp(e->line_num, e->u.primitive_op.op, es);
switch (e->u.primitive_op.op) {
case Operator::Neg:
ExpectType(e->line_num, "negation", MakeIntTypeVal(), ts[0]);
return TCResult(new_e, MakeIntTypeVal(), new_env);
case Operator::Add:
case Operator::Sub:
ExpectType(e->line_num, "subtraction(1)", MakeIntTypeVal(), ts[0]);
ExpectType(e->line_num, "substration(2)", MakeIntTypeVal(), ts[1]);
return TCResult(new_e, MakeIntTypeVal(), new_env);
case Operator::And:
ExpectType(e->line_num, "&&(1)", MakeBoolTypeVal(), ts[0]);
ExpectType(e->line_num, "&&(2)", MakeBoolTypeVal(), ts[1]);
return TCResult(new_e, MakeBoolTypeVal(), new_env);
case Operator::Or:
ExpectType(e->line_num, "||(1)", MakeBoolTypeVal(), ts[0]);
ExpectType(e->line_num, "||(2)", MakeBoolTypeVal(), ts[1]);
return TCResult(new_e, MakeBoolTypeVal(), new_env);
case Operator::Not:
ExpectType(e->line_num, "!", MakeBoolTypeVal(), ts[0]);
return TCResult(new_e, MakeBoolTypeVal(), new_env);
case Operator::Eq:
ExpectType(e->line_num, "==(1)", MakeIntTypeVal(), ts[0]);
ExpectType(e->line_num, "==(2)", MakeIntTypeVal(), ts[1]);
return TCResult(new_e, MakeBoolTypeVal(), new_env);
}
break;
}
case ExpressionKind::Call: {
auto fun_res = TypeCheckExp(e->u.call.function, env, ct_env, nullptr,
TCContext::ValueContext);
switch (fun_res.type->tag) {
case ValKind::FunctionTV: {
auto fun_t = fun_res.type;
auto arg_res =
TypeCheckExp(e->u.call.argument, fun_res.env, ct_env,
fun_t->u.fun_type.param, TCContext::ValueContext);
ExpectType(e->line_num, "call", fun_t->u.fun_type.param,
arg_res.type);
auto new_e = MakeCall(e->line_num, fun_res.exp, arg_res.exp);
return TCResult(new_e, fun_t->u.fun_type.ret, arg_res.env);
}
default: {
std::cerr << e->line_num
<< ": compilation error in call, expected a function"
<< std::endl;
PrintExp(e);
std::cerr << std::endl;
exit(-1);
}
}
break;
}
case ExpressionKind::FunctionT: {
switch (context) {
case TCContext::ValueContext:
case TCContext::TypeContext: {
auto pt = ToType(e->line_num,
InterpExp(ct_env, e->u.function_type.parameter));
auto rt = ToType(e->line_num,
InterpExp(ct_env, e->u.function_type.return_type));
auto new_e = MakeFunType(e->line_num, ReifyType(pt, e->line_num),
ReifyType(rt, e->line_num));
return TCResult(new_e, MakeTypeTypeVal(), env);
}
case TCContext::PatternContext: {
auto param_res = TypeCheckExp(e->u.function_type.parameter, env,
ct_env, nullptr, context);
auto ret_res = TypeCheckExp(e->u.function_type.return_type,
param_res.env, ct_env, nullptr, context);
auto new_e =
MakeFunType(e->line_num, ReifyType(param_res.type, e->line_num),
ReifyType(ret_res.type, e->line_num));
return TCResult(new_e, MakeTypeTypeVal(), ret_res.env);
}
}
}
case ExpressionKind::IntT:
case ExpressionKind::BoolT:
case ExpressionKind::TypeT:
case ExpressionKind::AutoT:
return TCResult(e, MakeTypeTypeVal(), env);
}
}
auto TypecheckCase(Value* expected, Expression* pat, Statement* body,
TypeEnv* env, Env* ct_env, Value* ret_type)
-> std::pair<Expression*, Statement*> {
auto pat_res =
TypeCheckExp(pat, env, ct_env, expected, TCContext::PatternContext);
auto res = TypeCheckStmt(body, pat_res.env, ct_env, ret_type);
return std::make_pair(pat, res.stmt);
}
auto TypeCheckStmt(Statement* s, TypeEnv* env, Env* ct_env, Value* ret_type)
-> TCStatement {
if (!s) {
return TCStatement(s, env);
}
switch (s->tag) {
case StatementKind::Match: {
auto res = TypeCheckExp(s->u.match_stmt.exp, env, ct_env, nullptr,
TCContext::ValueContext);
auto res_type = res.type;
auto new_clauses = new std::list<std::pair<Expression*, Statement*>>();
for (auto& clause : *s->u.match_stmt.clauses) {
new_clauses->push_back(TypecheckCase(
res_type, clause.first, clause.second, env, ct_env, ret_type));
}
Statement* new_s = MakeMatch(s->line_num, res.exp, new_clauses);
return TCStatement(new_s, env);
}
case StatementKind::While: {
auto cnd_res = TypeCheckExp(s->u.while_stmt.cond, env, ct_env, nullptr,
TCContext::ValueContext);
ExpectType(s->line_num, "condition of `while`", MakeBoolTypeVal(),
cnd_res.type);
auto body_res =
TypeCheckStmt(s->u.while_stmt.body, env, ct_env, ret_type);
auto new_s = MakeWhile(s->line_num, cnd_res.exp, body_res.stmt);
return TCStatement(new_s, env);
}
case StatementKind::Break:
case StatementKind::Continue:
return TCStatement(s, env);
case StatementKind::Block: {
auto stmt_res = TypeCheckStmt(s->u.block.stmt, env, ct_env, ret_type);
return TCStatement(MakeBlock(s->line_num, stmt_res.stmt), env);
}
case StatementKind::VariableDefinition: {
auto res = TypeCheckExp(s->u.variable_definition.init, env, ct_env,
nullptr, TCContext::ValueContext);
Value* rhs_ty = res.type;
auto lhs_res = TypeCheckExp(s->u.variable_definition.pat, env, ct_env,
rhs_ty, TCContext::PatternContext);
Statement* new_s =
MakeVarDef(s->line_num, s->u.variable_definition.pat, res.exp);
return TCStatement(new_s, lhs_res.env);
}
case StatementKind::Sequence: {
auto stmt_res = TypeCheckStmt(s->u.sequence.stmt, env, ct_env, ret_type);
auto env2 = stmt_res.env;
auto next_res = TypeCheckStmt(s->u.sequence.next, env2, ct_env, ret_type);
auto env3 = next_res.env;
return TCStatement(MakeSeq(s->line_num, stmt_res.stmt, next_res.stmt),
env3);
}
case StatementKind::Assign: {
auto rhs_res = TypeCheckExp(s->u.assign.rhs, env, ct_env, nullptr,
TCContext::ValueContext);
auto rhs_t = rhs_res.type;
auto lhs_res = TypeCheckExp(s->u.assign.lhs, env, ct_env, rhs_t,
TCContext::ValueContext);
auto lhs_t = lhs_res.type;
ExpectType(s->line_num, "assign", lhs_t, rhs_t);
auto new_s = MakeAssign(s->line_num, lhs_res.exp, rhs_res.exp);
return TCStatement(new_s, lhs_res.env);
}
case StatementKind::ExpressionStatement: {
auto res =
TypeCheckExp(s->u.exp, env, ct_env, nullptr, TCContext::ValueContext);
auto new_s = MakeExpStmt(s->line_num, res.exp);
return TCStatement(new_s, env);
}
case StatementKind::If: {
auto cnd_res = TypeCheckExp(s->u.if_stmt.cond, env, ct_env, nullptr,
TCContext::ValueContext);
ExpectType(s->line_num, "condition of `if`", MakeBoolTypeVal(),
cnd_res.type);
auto thn_res =
TypeCheckStmt(s->u.if_stmt.then_stmt, env, ct_env, ret_type);
auto els_res =
TypeCheckStmt(s->u.if_stmt.else_stmt, env, ct_env, ret_type);
auto new_s = MakeIf(s->line_num, cnd_res.exp, thn_res.stmt, els_res.stmt);
return TCStatement(new_s, env);
}
case StatementKind::Return: {
auto res = TypeCheckExp(s->u.return_stmt, env, ct_env, nullptr,
TCContext::ValueContext);
if (ret_type->tag == ValKind::AutoTV) {
// The following infers the return type from the first 'return'
// statement. This will get more difficult with subtyping, when we
// should infer the least-upper bound of all the 'return' statements.
*ret_type = *res.type;
} else {
ExpectType(s->line_num, "return", ret_type, res.type);
}
return TCStatement(MakeReturn(s->line_num, res.exp), env);
}
}
}
auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
-> Statement* {
if (!stmt) {
if (void_return) {
auto args = new std::vector<std::pair<std::string, Expression*>>();
return MakeReturn(line_num, MakeTuple(line_num, args));
} else {
std::cerr
<< "control-flow reaches end of non-void function without a return"
<< std::endl;
exit(-1);
}
}
switch (stmt->tag) {
case StatementKind::Match: {
auto new_clauses = new std::list<std::pair<Expression*, Statement*>>();
for (auto i = stmt->u.match_stmt.clauses->begin();
i != stmt->u.match_stmt.clauses->end(); ++i) {
auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
new_clauses->push_back(std::make_pair(i->first, s));
}
return MakeMatch(stmt->line_num, stmt->u.match_stmt.exp, new_clauses);
}
case StatementKind::Block:
return MakeBlock(
stmt->line_num,
CheckOrEnsureReturn(stmt->u.block.stmt, void_return, stmt->line_num));
case StatementKind::If:
return MakeIf(stmt->line_num, stmt->u.if_stmt.cond,
CheckOrEnsureReturn(stmt->u.if_stmt.then_stmt, void_return,
stmt->line_num),
CheckOrEnsureReturn(stmt->u.if_stmt.else_stmt, void_return,
stmt->line_num));
case StatementKind::Return:
return stmt;
case StatementKind::Sequence:
if (stmt->u.sequence.next) {
return MakeSeq(stmt->line_num, stmt->u.sequence.stmt,
CheckOrEnsureReturn(stmt->u.sequence.next, void_return,
stmt->line_num));
} else {
return CheckOrEnsureReturn(stmt->u.sequence.stmt, void_return,
stmt->line_num);
}
case StatementKind::Assign:
case StatementKind::ExpressionStatement:
case StatementKind::While:
case StatementKind::Break:
case StatementKind::Continue:
case StatementKind::VariableDefinition:
if (void_return) {
auto args = new std::vector<std::pair<std::string, Expression*>>();
return MakeSeq(
stmt->line_num, stmt,
MakeReturn(stmt->line_num, MakeTuple(stmt->line_num, args)));
} else {
std::cerr
<< stmt->line_num
<< ": control-flow reaches end of non-void function without a "
"return"
<< std::endl;
exit(-1);
}
}
}
auto TypeCheckFunDef(struct FunctionDefinition* f, TypeEnv* env, Env* ct_env)
-> struct FunctionDefinition* {
auto param_res = TypeCheckExp(f->param_pattern, env, ct_env, nullptr,
TCContext::PatternContext);
auto return_type = ToType(f->line_num, InterpExp(ct_env, f->return_type));
if (f->name == "main") {
ExpectType(f->line_num, "return type of `main`", MakeIntTypeVal(),
return_type);
// TODO: Check that main doesn't have any parameters.
}
auto res = TypeCheckStmt(f->body, param_res.env, ct_env, return_type);
bool void_return = TypeEqual(return_type, MakeVoidTypeVal());
auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
return MakeFunDef(f->line_num, f->name, ReifyType(return_type, f->line_num),
f->param_pattern, body);
}
auto TypeOfFunDef(TypeEnv* env, Env* ct_env, struct FunctionDefinition* fun_def)
-> Value* {
auto param_res = TypeCheckExp(fun_def->param_pattern, env, ct_env, nullptr,
TCContext::PatternContext);
auto param_type = ToType(fun_def->line_num, param_res.type);
auto ret = InterpExp(ct_env, fun_def->return_type);
if (ret->tag == ValKind::AutoTV) {
auto f = TypeCheckFunDef(fun_def, env, ct_env);
ret = InterpExp(ct_env, f->return_type);
}
return MakeFunTypeVal(param_type, ret);
}
auto TypeOfStructDef(struct StructDefinition* sd, TypeEnv* /*env*/, Env* ct_top)
-> Value* {
auto fields = new VarValues();
auto methods = new VarValues();
for (auto m = sd->members->begin(); m != sd->members->end(); ++m) {
if ((*m)->tag == MemberKind::FieldMember) {
auto t = ToType(sd->line_num, InterpExp(ct_top, (*m)->u.field.type));
fields->push_back(std::make_pair(*(*m)->u.field.name, t));
}
}
return MakeStructTypeVal(*sd->name, fields, methods);
}
auto NameOfDecl(Declaration* d) -> std::string {
switch (d->tag) {
case DeclarationKind::FunctionDeclaration:
return d->u.fun_def->name;
case DeclarationKind::StructDeclaration:
return *d->u.struct_def->name;
case DeclarationKind::ChoiceDeclaration:
return *d->u.choice_def.name;
}
}
auto TypeCheckDecl(Declaration* d, TypeEnv* env, Env* ct_env) -> Declaration* {
switch (d->tag) {
case DeclarationKind::StructDeclaration: {
auto members = new std::list<Member*>();
for (auto& member : *d->u.struct_def->members) {
switch (member->tag) {
case MemberKind::FieldMember: {
// TODO: Interpret the type expression and store the result.
members->push_back(member);
break;
}
}
}
return MakeStructDecl(d->u.struct_def->line_num, *d->u.struct_def->name,
members);
}
case DeclarationKind::FunctionDeclaration:
return MakeFunDecl(TypeCheckFunDef(d->u.fun_def, env, ct_env));
case DeclarationKind::ChoiceDeclaration:
return d; // TODO.
}
}
auto TopLevel(std::list<Declaration*>* fs) -> std::pair<TypeEnv*, Env*> {
TypeEnv* top = nullptr;
Env* ct_top = nullptr;
bool found_main = false;
for (auto d : *fs) {
if (NameOfDecl(d) == "main") {
found_main = true;
}
switch (d->tag) {
case DeclarationKind::FunctionDeclaration: {
auto t = TypeOfFunDef(top, ct_top, d->u.fun_def);
top = new TypeEnv(NameOfDecl(d), t, top);
break;
}
case DeclarationKind::StructDeclaration: {
auto st = TypeOfStructDef(d->u.struct_def, top, ct_top);
Address a = AllocateValue(st);
ct_top = new Env(NameOfDecl(d), a, ct_top); // Is this obsolete?
auto params = MakeTupleTypeVal(st->u.struct_type.fields);
auto fun_ty = MakeFunTypeVal(params, st);
top = new TypeEnv(NameOfDecl(d), fun_ty, top);
break;
}
case DeclarationKind::ChoiceDeclaration: {
auto alts = new VarValues();
for (auto i = d->u.choice_def.alternatives->begin();
i != d->u.choice_def.alternatives->end(); ++i) {
auto t =
ToType(d->u.choice_def.line_num, InterpExp(ct_top, i->second));
alts->push_back(std::make_pair(i->first, t));
}
auto ct = MakeChoiceTypeVal(d->u.choice_def.name, alts);
Address a = AllocateValue(ct);
ct_top = new Env(NameOfDecl(d), a, ct_top); // Is this obsolete?
top = new TypeEnv(NameOfDecl(d), ct, top);
break;
}
} // switch (d->tag)
} // for
if (found_main == false) {
std::cerr << "error, program must contain a function named `main`"
<< std::endl;
exit(-1);
}
return make_pair(top, ct_top);
}
} // namespace Carbon
@@ -0,0 +1,56 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_TYPECHECK_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_TYPECHECK_H_
#include <set>
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/statement.h"
#include "executable_semantics/interpreter/assoc_list.h"
#include "executable_semantics/interpreter/interpreter.h"
namespace Carbon {
using TypeEnv = AssocList<std::string, Value*>;
void PrintTypeEnv(TypeEnv* env);
enum class TCContext { ValueContext, PatternContext, TypeContext };
struct TCResult {
TCResult(Expression* e, Value* t, TypeEnv* env) : exp(e), type(t), env(env) {}
Expression* exp;
Value* type;
TypeEnv* env;
};
struct TCStatement {
TCStatement(Statement* s, TypeEnv* e) : stmt(s), env(e) {}
Statement* stmt;
TypeEnv* env;
};
auto ToType(int line_num, Value* val) -> Value*;
auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
TCContext context) -> TCResult;
auto TypeCheckStmt(Statement*, TypeEnv*, Env*, Value*) -> TCStatement;
auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv*)
-> struct FunctionDefinition*;
auto TypeCheckDecl(Declaration* d, TypeEnv* env, Env* ct_env) -> Declaration*;
auto TopLevel(std::list<Declaration*>* fs) -> std::pair<TypeEnv*, Env*>;
void PrintErrorString(const std::string& s);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_TYPECHECK_H_
+402
View File
@@ -0,0 +1,402 @@
// 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
#include "executable_semantics/interpreter/value.h"
#include <iostream>
#include "executable_semantics/interpreter/interpreter.h"
namespace Carbon {
auto FindInVarValues(const std::string& field, VarValues* inits) -> Value* {
for (auto& i : *inits) {
if (i.first == field) {
return i.second;
}
}
return nullptr;
}
auto FieldsEqual(VarValues* ts1, VarValues* ts2) -> bool {
if (ts1->size() == ts2->size()) {
for (auto& iter1 : *ts1) {
auto t2 = FindInVarValues(iter1.first, ts2);
if (t2 == nullptr) {
return false;
}
if (!TypeEqual(iter1.second, t2)) {
return false;
}
}
return true;
} else {
return false;
}
}
auto MakeIntVal(int i) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::IntV;
v->u.integer = i;
return v;
}
auto MakeBoolVal(bool b) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::BoolV;
v->u.boolean = b;
return v;
}
auto MakeFunVal(std::string name, Value* param, Statement* body) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::FunV;
v->u.fun.name = new std::string(std::move(name));
v->u.fun.param = param;
v->u.fun.body = body;
return v;
}
auto MakePtrVal(Address addr) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::PtrV;
v->u.ptr = addr;
return v;
}
auto MakeStructVal(Value* type, Value* inits) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::StructV;
v->u.struct_val.type = type;
v->u.struct_val.inits = inits;
return v;
}
auto MakeTupleVal(std::vector<std::pair<std::string, Address>>* elts)
-> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::TupleV;
v->u.tuple.elts = elts;
return v;
}
auto MakeAltVal(std::string alt_name, std::string choice_name, Value* arg)
-> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::AltV;
v->u.alt.alt_name = new std::string(std::move(alt_name));
v->u.alt.choice_name = new std::string(std::move(choice_name));
v->u.alt.arg = arg;
return v;
}
auto MakeAltCons(std::string alt_name, std::string choice_name) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::AltConsV;
v->u.alt.alt_name = new std::string(std::move(alt_name));
v->u.alt.choice_name = new std::string(std::move(choice_name));
return v;
}
auto MakeVarPatVal(std::string name, Value* type) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::VarPatV;
v->u.var_pat.name = new std::string(std::move(name));
v->u.var_pat.type = type;
return v;
}
auto MakeVarTypeVal(std::string name) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::VarTV;
v->u.var_type = new std::string(std::move(name));
return v;
}
auto MakeIntTypeVal() -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::IntTV;
return v;
}
auto MakeBoolTypeVal() -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::BoolTV;
return v;
}
auto MakeTypeTypeVal() -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::TypeTV;
return v;
}
auto MakeAutoTypeVal() -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::AutoTV;
return v;
}
auto MakeFunTypeVal(Value* param, Value* ret) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::FunctionTV;
v->u.fun_type.param = param;
v->u.fun_type.ret = ret;
return v;
}
auto MakePtrTypeVal(Value* type) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::PointerTV;
v->u.ptr_type.type = type;
return v;
}
auto MakeStructTypeVal(std::string name, VarValues* fields, VarValues* methods)
-> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::StructTV;
v->u.struct_type.name = new std::string(std::move(name));
v->u.struct_type.fields = fields;
v->u.struct_type.methods = methods;
return v;
}
auto MakeTupleTypeVal(VarValues* fields) -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::TupleTV;
v->u.tuple_type.fields = fields;
return v;
}
auto MakeVoidTypeVal() -> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::TupleTV;
v->u.tuple_type.fields = new VarValues();
return v;
}
auto MakeChoiceTypeVal(std::string* name,
std::list<std::pair<std::string, Value*>>* alts)
-> Value* {
auto* v = new Value();
v->alive = true;
v->tag = ValKind::ChoiceTV;
v->u.choice_type.name = name;
v->u.choice_type.alternatives = alts;
return v;
}
void PrintValue(Value* val, std::ostream& out) {
if (!val->alive) {
out << "!!";
}
switch (val->tag) {
case ValKind::AltConsV: {
out << *val->u.alt_cons.choice_name << "." << *val->u.alt_cons.alt_name;
break;
}
case ValKind::VarPatV: {
PrintValue(val->u.var_pat.type, out);
out << ": " << *val->u.var_pat.name;
break;
}
case ValKind::AltV: {
out << "alt " << *val->u.alt.choice_name << "." << *val->u.alt.alt_name
<< " ";
PrintValue(val->u.alt.arg, out);
break;
}
case ValKind::StructV: {
out << *val->u.struct_val.type->u.struct_type.name;
PrintValue(val->u.struct_val.inits, out);
break;
}
case ValKind::TupleV: {
out << "(";
bool add_commas = false;
for (const auto& elt : *val->u.tuple.elts) {
if (add_commas) {
out << ", ";
} else {
add_commas = true;
}
out << elt.first << " = ";
PrintValue(state->heap[elt.second], out);
out << "@" << elt.second;
}
out << ")";
break;
}
case ValKind::IntV:
out << val->u.integer;
break;
case ValKind::BoolV:
out << std::boolalpha << val->u.boolean;
break;
case ValKind::FunV:
out << "fun<" << *val->u.fun.name << ">";
break;
case ValKind::PtrV:
out << "ptr<" << val->u.ptr << ">";
break;
case ValKind::BoolTV:
out << "Bool";
break;
case ValKind::IntTV:
out << "Int";
break;
case ValKind::TypeTV:
out << "Type";
break;
case ValKind::AutoTV:
out << "auto";
break;
case ValKind::PointerTV:
out << "Ptr(";
PrintValue(val->u.ptr_type.type, out);
out << ")";
break;
case ValKind::FunctionTV:
out << "fn ";
PrintValue(val->u.fun_type.param, out);
out << " -> ";
PrintValue(val->u.fun_type.ret, out);
break;
case ValKind::VarTV:
out << *val->u.var_type;
break;
case ValKind::TupleTV: {
out << "Tuple(";
bool add_commas = false;
for (const auto& elt : *val->u.tuple_type.fields) {
if (add_commas) {
out << ", ";
} else {
add_commas = true;
}
out << elt.first << " = ";
PrintValue(elt.second, out);
}
out << ")";
break;
}
case ValKind::StructTV:
out << "struct " << *val->u.struct_type.name;
break;
case ValKind::ChoiceTV:
out << "choice " << *val->u.choice_type.name;
break;
}
}
auto TypeEqual(Value* t1, Value* t2) -> bool {
if (t1->tag != t2->tag) {
return false;
}
switch (t1->tag) {
case ValKind::VarTV:
return *t1->u.var_type == *t2->u.var_type;
case ValKind::PointerTV:
return TypeEqual(t1->u.ptr_type.type, t2->u.ptr_type.type);
case ValKind::FunctionTV:
return TypeEqual(t1->u.fun_type.param, t2->u.fun_type.param) &&
TypeEqual(t1->u.fun_type.ret, t2->u.fun_type.ret);
case ValKind::StructTV:
return *t1->u.struct_type.name == *t2->u.struct_type.name;
case ValKind::ChoiceTV:
return *t1->u.choice_type.name == *t2->u.choice_type.name;
case ValKind::TupleTV:
return FieldsEqual(t1->u.tuple_type.fields, t2->u.tuple_type.fields);
case ValKind::IntTV:
case ValKind::BoolTV:
return true;
default:
return false;
}
}
static auto FieldsValueEqual(VarValues* ts1, VarValues* ts2, int line_num)
-> bool {
if (ts1->size() != ts2->size()) {
return false;
}
for (auto& iter1 : *ts1) {
auto t2 = FindInVarValues(iter1.first, ts2);
if (t2 == nullptr) {
return false;
}
if (!ValueEqual(iter1.second, t2, line_num)) {
return false;
}
}
return true;
}
auto ValueEqual(Value* v1, Value* v2, int line_num) -> bool {
CheckAlive(v1, line_num);
CheckAlive(v2, line_num);
if (v1->tag != v2->tag) {
return false;
}
switch (v1->tag) {
case ValKind::IntV:
return v1->u.integer == v2->u.integer;
case ValKind::BoolV:
return v1->u.boolean == v2->u.boolean;
case ValKind::PtrV:
return v1->u.ptr == v2->u.ptr;
case ValKind::FunV:
return v1->u.fun.body == v2->u.fun.body;
case ValKind::TupleV:
return FieldsValueEqual(v1->u.tuple_type.fields, v2->u.tuple_type.fields,
line_num);
default:
return TypeEqual(v1, v2);
}
}
auto ToInteger(Value* v) -> int {
switch (v->tag) {
case ValKind::IntV:
return v->u.integer;
default:
std::cerr << "expected an integer, not ";
PrintValue(v, std::cerr);
exit(-1);
}
}
void CheckAlive(Value* v, int line_num) {
if (!v->alive) {
std::cerr << line_num << ": undefined behavior: access to dead value ";
PrintValue(v, std::cerr);
std::cerr << std::endl;
exit(-1);
}
}
} // namespace Carbon
+139
View File
@@ -0,0 +1,139 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
#include <list>
#include <vector>
#include "executable_semantics/ast/statement.h"
namespace Carbon {
struct Value;
using Address = unsigned int;
using VarValues = std::list<std::pair<std::string, Value*>>;
auto FindInVarValues(const std::string& field, VarValues* inits) -> Value*;
auto FieldsEqual(VarValues* ts1, VarValues* ts2) -> bool;
enum class ValKind {
IntV,
FunV,
PtrV,
BoolV,
StructV,
AltV,
TupleV,
VarTV,
IntTV,
BoolTV,
TypeTV,
FunctionTV,
PointerTV,
AutoTV,
TupleTV,
StructTV,
ChoiceTV,
VarPatV,
AltConsV
};
struct Value {
ValKind tag;
bool alive;
union {
int integer;
bool boolean;
struct {
std::string* name;
Value* param;
Statement* body;
} fun;
struct {
Value* type;
Value* inits;
} struct_val;
struct {
std::string* alt_name;
std::string* choice_name;
} alt_cons;
struct {
std::string* alt_name;
std::string* choice_name;
Value* arg;
} alt;
struct {
std::vector<std::pair<std::string, Address>>* elts;
} tuple;
Address ptr;
std::string* var_type;
struct {
std::string* name;
Value* type;
} var_pat;
struct {
Value* param;
Value* ret;
} fun_type;
struct {
Value* type;
} ptr_type;
struct {
std::string* name;
VarValues* fields;
VarValues* methods;
} struct_type;
struct {
std::string* name;
VarValues* fields;
} tuple_type;
struct {
std::string* name;
VarValues* alternatives;
} choice_type;
struct {
std::list<std::string*>* params;
Value* type;
} implicit;
} u;
};
auto MakeIntVal(int i) -> Value*;
auto MakeBoolVal(bool b) -> Value*;
auto MakeFunVal(std::string name, Value* param, Statement* body) -> Value*;
auto MakePtrVal(Address addr) -> Value*;
auto MakeStructVal(Value* type, Value* inits) -> Value*;
auto MakeTupleVal(std::vector<std::pair<std::string, Address>>* elts) -> Value*;
auto MakeAltVal(std::string alt_name, std::string choice_name, Value* arg)
-> Value*;
auto MakeAltCons(std::string alt_name, std::string choice_name) -> Value*;
auto MakeVarPatVal(std::string name, Value* type) -> Value*;
auto MakeVarTypeVal(std::string name) -> Value*;
auto MakeIntTypeVal() -> Value*;
auto MakeAutoTypeVal() -> Value*;
auto MakeBoolTypeVal() -> Value*;
auto MakeTypeTypeVal() -> Value*;
auto MakeFunTypeVal(Value* param, Value* ret) -> Value*;
auto MakePtrTypeVal(Value* type) -> Value*;
auto MakeStructTypeVal(std::string name, VarValues* fields, VarValues* methods)
-> Value*;
auto MakeTupleTypeVal(VarValues* fields) -> Value*;
auto MakeVoidTypeVal() -> Value*;
auto MakeChoiceTypeVal(std::string* name, VarValues* alts) -> Value*;
void PrintValue(Value* val, std::ostream& out);
auto TypeEqual(Value* t1, Value* t2) -> bool;
auto ValueEqual(Value* v1, Value* v2, int line_num) -> bool;
auto ToInteger(Value* v) -> int;
void CheckAlive(Value* v, int line_num);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
+27
View File
@@ -0,0 +1,27 @@
// 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
#include <cstdio>
#include <cstring>
#include <iostream>
#include "executable_semantics/syntax_helpers.h"
extern FILE* yyin;
extern auto yyparse() -> int; // NOLINT(readability-identifier-naming)
int main(int argc, char* argv[]) {
// yydebug = 1;
if (argc > 1) {
Carbon::input_filename = argv[1];
yyin = fopen(argv[1], "r");
if (yyin == nullptr) {
std::cerr << "Error opening '" << argv[1] << "': " << strerror(errno)
<< std::endl;
return 1;
}
}
return yyparse();
}
+90
View File
@@ -0,0 +1,90 @@
/*
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
*/
%{
#include <cstdlib>
#include "executable_semantics/syntax.tab.h"
%}
%option yylineno
AND "and"
ARROW "->"
AUTO "auto"
BOOL "Bool"
BREAK "break"
CASE "case"
CHOICE "choice"
COMMENT \/\/[^\n]*\n
CONTINUE "continue"
DBLARROW "=>"
DEFAULT "default"
ELSE "else"
EQUAL "=="
FALSE "false"
FN "fn"
FNTY "fnty"
IF "if"
INT "Int"
MATCH "match"
NOT "not"
OR "or"
RETURN "return"
STRUCT "struct"
TRUE "true"
TYPE "Type"
VAR "var"
WHILE "while"
identifier [A-Za-z_][A-Za-z0-9_]*
integer_literal [0-9]+
%%
{AND} { return AND; }
{ARROW} { return ARROW; }
{AUTO} { return AUTO; }
{BOOL} { return BOOL; }
{BREAK} { return BREAK; }
{CASE} { return CASE; }
{CHOICE} { return CHOICE; }
{COMMENT} ;
{CONTINUE} { return CONTINUE; }
{DBLARROW} { return DBLARROW; }
{DEFAULT} { return DEFAULT; }
{ELSE} { return ELSE; }
{EQUAL} { return EQUAL; }
{FALSE} { return FALSE; }
{FN} { return FN; }
{FNTY} { return FNTY; }
{IF} { return IF; }
{INT} { return INT; }
{MATCH} { return MATCH; }
{NOT} { return NOT; }
{OR} { return OR; }
{RETURN} { return RETURN; }
{STRUCT} { return STRUCT; }
{TRUE} { return TRUE; }
{TYPE} { return TYPE; }
{VAR} { return VAR; }
{WHILE} { return WHILE; }
{identifier} {
int n = strlen(yytext);
yylval.str = reinterpret_cast<char*>(malloc((n + 1) * sizeof(char)));
strncpy(yylval.str, yytext, n + 1);
return identifier;
}
{integer_literal} {
yylval.num = atof(yytext);
return integer_literal;
}
[ \t\n]+ ;
. { return yytext[0]; }
%%
int yywrap() { return 1; }
+314
View File
@@ -0,0 +1,314 @@
// 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
%code top {
#include <algorithm>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <list>
#include "executable_semantics/syntax_helpers.h"
}
%code requires {
#include "executable_semantics/ast/declaration.h"
#include "executable_semantics/ast/expression_or_field_list.h"
#include "executable_semantics/ast/function_definition.h"
}
%code {
extern int yylineno;
extern int yylex();
void yyerror(char* error) {
Carbon::PrintSyntaxError(error, yylineno);
}
// void yyerror(char* error, ...);
}
%union {
char* str;
int num;
Carbon::Expression* expression;
std::list<std::pair<std::string, Carbon::Expression*>>* field_types;
Carbon::Statement* statement;
Carbon::Statement* statement_list;
Carbon::FunctionDefinition* function_definition;
Carbon::Declaration* declaration;
std::list<Carbon::Declaration*>* declaration_list;
Carbon::Member* member;
std::list<Carbon::Member*>* member_list;
Carbon::ExpOrFieldList* field_list;
std::pair<std::string, Carbon::Expression*>* alternative;
std::list<std::pair<std::string, Carbon::Expression*>>* alternative_list;
std::pair<Carbon::Expression*, Carbon::Statement*>* clause;
std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>* clause_list;
Carbon::Expression* fun_type;
};
%token <num> integer_literal
%token <str> identifier
%type <str> designator
%type <declaration> declaration
%type <function_definition> function_declaration
%type <function_definition> function_definition
%type <declaration_list> declaration_list
%type <statement> statement
%type <statement_list> statement_list
%type <expression> expression
%type <expression> pattern
%type <expression> return_type
%type <expression> tuple
%type <member> member
%type <member_list> member_list
%type <field_list> field
%type <field_list> field_list
%type <alternative> alternative
%type <alternative_list> alternative_list
%type <clause> clause
%type <clause_list> clause_list
%token AND
%token OR
%token NOT
%token INT
%token BOOL
%token TYPE
%token FN
%token FNTY
%token ARROW
%token VAR
%token EQUAL
%token IF
%token ELSE
%token WHILE
%token BREAK
%token CONTINUE
%token RETURN
%token TRUE
%token FALSE
%token STRUCT
%token CHOICE
%token MATCH
%token CASE
%token DBLARROW
%token DEFAULT
%token AUTO
%nonassoc '{' '}'
%nonassoc ':' ',' DBLARROW
%left OR AND
%nonassoc EQUAL NOT
%left '+' '-'
%left '.' ARROW
%nonassoc '(' ')' '[' ']'
%start input
%locations
%%
input: declaration_list
{ Carbon::ExecProgram($1); }
;
pattern:
expression
{ $$ = $1; }
;
expression:
identifier
{ $$ = Carbon::MakeVar(yylineno, $1); }
| expression designator
{ $$ = Carbon::MakeGetField(yylineno, $1, $2); }
| expression '[' expression ']'
{ $$ = Carbon::MakeIndex(yylineno, $1, $3); }
| expression ':' identifier
{ $$ = Carbon::MakeVarPat(yylineno, $3, $1); }
| integer_literal
{ $$ = Carbon::MakeInt(yylineno, $1); }
| TRUE
{ $$ = Carbon::MakeBool(yylineno, true); }
| FALSE
{ $$ = Carbon::MakeBool(yylineno, false); }
| INT
{ $$ = Carbon::MakeIntType(yylineno); }
| BOOL
{ $$ = Carbon::MakeBoolType(yylineno); }
| TYPE
{ $$ = Carbon::MakeTypeType(yylineno); }
| AUTO
{ $$ = Carbon::MakeAutoType(yylineno); }
| tuple { $$ = $1; }
| expression EQUAL expression
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
| expression '+' expression
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
| expression '-' expression
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
| expression AND expression
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
| expression OR expression
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
| NOT expression
{ $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
| '-' expression
{ $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
| expression tuple
{
if ($2->tag == Carbon::ExpressionKind::Tuple) {
$$ = Carbon::MakeCall(yylineno, $1, $2);
} else {
auto vec =
new std::vector<std::pair<std::string, Carbon::Expression*>>();
vec->push_back(std::make_pair("", $2));
$$ = Carbon::MakeCall(yylineno, $1, Carbon::MakeTuple(yylineno, vec));
}
}
| FNTY tuple return_type
{ $$ = Carbon::MakeFunType(yylineno, $2, $3); }
;
designator: '.' identifier { $$ = $2; }
;
tuple: '(' field_list ')'
{
switch ($2->tag) {
case Carbon::ExpOrFieldListKind::Exp:
$$ = $2->u.exp;
break;
case Carbon::ExpOrFieldListKind::FieldList:
auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
$2->u.fields->begin(), $2->u.fields->end());
$$ = Carbon::MakeTuple(yylineno, vec);
break;
}
}
;
field:
pattern
{ $$ = Carbon::MakeExp($1); }
| designator '=' pattern
{
auto fields =
new std::list<std::pair<std::string, Carbon::Expression*>>();
fields->push_back(std::make_pair($1, $3));
$$ = Carbon::MakeFieldList(fields);
}
;
field_list:
// Empty
{
$$ = Carbon::MakeFieldList(
new std::list<std::pair<std::string, Carbon::Expression*>>());
}
| field
{ $$ = $1; }
| field ',' field_list
{ $$ = Carbon::MakeConsField($1, $3); }
;
clause:
CASE pattern DBLARROW statement
{ $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>($2, $4); }
| DEFAULT DBLARROW statement
{
auto vp = Carbon::MakeVarPat(yylineno, "_",
Carbon::MakeAutoType(yylineno));
$$ = new std::pair<Carbon::Expression*, Carbon::Statement*>(vp, $3);
}
;
clause_list:
// Empty
{
$$ = new std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>();
}
| clause clause_list
{ $$ = $2; $$->push_front(*$1); }
;
statement:
expression '=' expression ';'
{ $$ = Carbon::MakeAssign(yylineno, $1, $3); }
| VAR pattern '=' expression ';'
{ $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
| expression ';'
{ $$ = Carbon::MakeExpStmt(yylineno, $1); }
| IF '(' expression ')' statement ELSE statement
{ $$ = Carbon::MakeIf(yylineno, $3, $5, $7); }
| WHILE '(' expression ')' statement
{ $$ = Carbon::MakeWhile(yylineno, $3, $5); }
| BREAK ';'
{ $$ = Carbon::MakeBreak(yylineno); }
| CONTINUE ';'
{ $$ = Carbon::MakeContinue(yylineno); }
| RETURN expression ';'
{ $$ = Carbon::MakeReturn(yylineno, $2); }
| '{' statement_list '}'
{ $$ = Carbon::MakeBlock(yylineno, $2); }
| MATCH '(' expression ')' '{' clause_list '}'
{ $$ = Carbon::MakeMatch(yylineno, $3, $6); }
;
statement_list:
// Empty
{ $$ = 0; }
| statement statement_list
{ $$ = Carbon::MakeSeq(yylineno, $1, $2); }
;
return_type:
// Empty
{
$$ = Carbon::MakeTuple(
yylineno,
new std::vector<std::pair<std::string, Carbon::Expression*>>());
}
| ARROW expression
{ $$ = $2; }
;
function_definition:
FN identifier tuple return_type '{' statement_list '}'
{ $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
| FN identifier tuple DBLARROW expression ';'
{
$$ = Carbon::MakeFunDef(yylineno, $2, Carbon::MakeAutoType(yylineno), $3,
Carbon::MakeReturn(yylineno, $5));
}
;
function_declaration:
FN identifier tuple return_type ';'
{ $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
;
member:
VAR expression ':' identifier ';'
{ $$ = MakeField(yylineno, $4, $2); }
;
member_list:
// Empty
{ $$ = new std::list<Carbon::Member*>(); }
| member member_list
{ $$ = $2; $$->push_front($1); }
;
alternative:
identifier tuple ';'
{ $$ = new std::pair<std::string, Carbon::Expression*>($1, $2); }
;
alternative_list:
// Empty
{ $$ = new std::list<std::pair<std::string, Carbon::Expression*>>(); }
| alternative alternative_list
{ $$ = $2; $$->push_front(*$1); }
;
declaration:
function_definition
{ $$ = Carbon::MakeFunDecl($1); }
| function_declaration
{ $$ = Carbon::MakeFunDecl($1); }
| STRUCT identifier '{' member_list '}'
{ $$ = Carbon::MakeStructDecl(yylineno, $2, $4); }
| CHOICE identifier '{' alternative_list '}'
{ $$ = Carbon::MakeChoiceDecl(yylineno, $2, $4); }
;
declaration_list:
// Empty
{ $$ = new std::list<Carbon::Declaration*>(); }
| declaration declaration_list
{
$$ = $2;
$$->push_front($1);
}
;
%%
+45
View File
@@ -0,0 +1,45 @@
// 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
#include "executable_semantics/syntax_helpers.h"
#include <iostream>
#include "executable_semantics/interpreter/interpreter.h"
#include "executable_semantics/interpreter/typecheck.h"
namespace Carbon {
char* input_filename = nullptr;
void PrintSyntaxError(char* error, int line_num) {
std::cerr << input_filename << ":" << line_num << ": " << error << std::endl;
exit(-1);
}
void ExecProgram(std::list<Declaration*>* fs) {
std::cout << "********** source program **********" << std::endl;
for (const auto& decl : *fs) {
PrintDecl(decl);
}
std::cout << "********** type checking **********" << std::endl;
state = new State(); // Compile-time state.
std::pair<TypeEnv*, Env*> p = TopLevel(fs);
TypeEnv* top = p.first;
Env* ct_top = p.second;
std::list<Declaration*> new_decls;
for (const auto& i : *fs) {
new_decls.push_back(TypeCheckDecl(i, top, ct_top));
}
std::cout << std::endl;
std::cout << "********** type checking complete **********" << std::endl;
for (const auto& decl : new_decls) {
PrintDecl(decl);
}
std::cout << "********** starting execution **********" << std::endl;
int result = InterpProgram(&new_decls);
std::cout << "result: " << result << std::endl;
}
} // namespace Carbon
+29
View File
@@ -0,0 +1,29 @@
// 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
// Helpers should be added here when logic in syntax.ypp is more than a single
// statement. The intent is to minimize the amount of C++ in the .ypp file, to
// improve ease of maintenance.
#ifndef EXECUTABLE_SEMANTICS_EXEC_H_
#define EXECUTABLE_SEMANTICS_EXEC_H_
#include <list>
#include "executable_semantics/ast/declaration.h"
namespace Carbon {
// Initialized by main(), and used when printing errors.
extern char* input_filename;
// Prints errors.
void PrintSyntaxError(char* error, int line_num);
// Runs the top-level declaration list.
void ExecProgram(std::list<Declaration*>* fs);
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_EXEC_H_
+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
fn main() -> Int {
var Int: x = 0;
{
var Int: x = 1;
}
return x;
}
+265
View File
@@ -0,0 +1,265 @@
********** source program **********
fn main () -> Int {
var Int: x = 0;
{
var Int: x = 1;
}
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn main () -> Int {
var Int: x = 0;
{
var Int: x = 1;
}
return x;
}
********** 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{var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 0; ... --->
{
stack: main{var Int: x = 0;<-1> :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 0; --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 0 with var Int: x = 0;<1>(0,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: {
...
}
... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
pattern_match(Int: x, 0)
{
stack: main{{
...
}
... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt {
...
}
... --->
{
stack: main{{
...
}
<-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{var Int: x = 1;<-1> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt var Int: x = 1; --->
{
stack: main{var Int: x = 1;<-1> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt var Int: x = 1; --->
{
stack: main{1<-1> :: var Int: x = 1;<0> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: var Int: x = 1;<0> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 1 with var Int: x = 1;<1>(1,) --->
{
stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value Int: x with var Int: x = 1;<2>(1,Int: x,) --->
pattern_match(Int: x, 1)
{
stack: main{{
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, 0, 1,
env: x: 1, x: 0, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, 0, !!1,
env: x: 0, main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0, !!1,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0, !!1,
env: x: 0, main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!0, !!1,
env: main: fun<main>,
}
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
fn main() -> Int {
var Int: x = 2;
while (true) {
if (x == 0)
break;
else
x = x - 1;
}
return x;
}
+821
View File
@@ -0,0 +1,821 @@
MakeBlock
********** source program **********
fn main () -> Int {
var Int: x = 2;
while (true)
{
if ((x == 0))
break;
else
x = (x - 1);
}
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn main () -> Int {
var Int: x = 2;
while (true)
{
if ((x == 0))
break;
else
x = (x - 1);
}
return x;
}
********** 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{var Int: x = 2; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 2; ... --->
{
stack: main{var Int: x = 2;<-1> :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 2; --->
{
stack: main{2<-1> :: var Int: x = 2;<0> :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: var Int: x = 2;<0> :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with var Int: x = 2;<1>(2,) --->
{
stack: main{Int: x<-1> :: var Int: x = 2;<1>(2,) :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 2;<1>(2,) :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 2;<1>(2,) :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 2;<1>(2,) :: while (true)
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int: x with var Int: x = 2;<2>(2,Int: x,) --->
pattern_match(Int: x, 2)
{
stack: main{while (true)
... ... <-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while (true)
... ... --->
{
stack: main{while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while (true)
... --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp true --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value true with while (true)
... <1>(true,) --->
{
stack: main{{
...
}
<-1> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{(x == 0)<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x == 0)<1>(2,) --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(2,0,) --->
{
stack: main{false<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value false with if ((x == 0))
...
else
... <1>(false,) --->
{
stack: main{x = (x - 1);<-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x - 1)<1>(2,) --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(2,1,) --->
{
stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
{
stack: main{{
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt while (true)
... --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp true --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value true with while (true)
... <1>(true,) --->
{
stack: main{{
...
}
<-1> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{(x == 0)<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x == 0)<1>(1,) --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(1,0,) --->
{
stack: main{false<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value false with if ((x == 0))
...
else
... <1>(false,) --->
{
stack: main{x = (x - 1);<-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
{
stack: main{{
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt while (true)
... --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp true --->
{
stack: main{true<-1> :: while (true)
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value true with while (true)
... <1>(true,) --->
{
stack: main{{
...
}
<-1> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{if ((x == 0))
...
else
... <-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt if ((x == 0))
...
else
... --->
{
stack: main{(x == 0)<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: (x == 0)<0> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<1>(0,) --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(0,0,) --->
{
stack: main{true<-1> :: if ((x == 0))
...
else
... <0> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value true with if ((x == 0))
...
else
... <1>(true,) --->
{
stack: main{break;<-1> :: {
...
}
<0> :: while (true)
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt break; --->
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!0,
env: main: fun<main>,
}
result: 0
+32
View File
@@ -0,0 +1,32 @@
// 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
choice Ints {
None();
One(Int);
Two(Int,Int);
}
fn main() -> Int {
var auto: x = Ints.None();
var auto: y = Ints.One(42);
var auto: n = 0;
match (y) {
case Ints.None() =>
n = n + 2;
case Ints.One(auto: x) =>
n = x + 1 - 42;
case Ints.Two(auto: a, auto: b) =>
n = 2;
}
match (x) {
case Ints.One(auto: x) =>
n = x + 2;
case Ints.None() =>
n = n - 1;
case Ints.Two(auto: x, auto: y) =>
n = 5;
}
return n;
}
+43
View File
@@ -0,0 +1,43 @@
********** source program **********
choice Ints {
alt None ();
alt One Int;
alt Two (0 = Int, 1 = Int);
}
fn main () -> Int {
var auto: x = Ints.None();
var auto: y = Ints.One(0 = 42);
var auto: n = 0;
match (y) {
case Ints.None() =>
n = (n + 2);
case Ints.One(0 = auto: x) =>
n = ((x + 1) - 42);
case Ints.Two(0 = auto: a, 1 = auto: b) =>
n = 2;
}
match (x) {
case Ints.One(0 = auto: x) =>
n = (x + 2);
case Ints.None() =>
n = (n - 1);
case Ints.Two(0 = auto: x, 1 = auto: y) =>
n = 5;
}
return n;
}
********** type checking **********
--- step exp () --->
--- step exp Int --->
--- step exp (0 = Int, 1 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
13: type error in call
expected: Int
actual: Tuple(0 = Int)
+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
fn main() -> Int {
var auto: x = 2;
while (not (x == 0)) {
x = x - 1;
continue;
x = x + 1;
}
return x;
}
+616
View File
@@ -0,0 +1,616 @@
********** source program **********
fn main () -> Int {
var auto: x = 2;
while ((! (x == 0)))
{
x = (x - 1);
continue;
x = (x + 1);
}
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: x = 2;
while ((! (x == 0)))
{
x = (x - 1);
continue;
x = (x + 1);
}
return x;
}
********** 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{var auto: x = 2; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 2; ... --->
{
stack: main{var auto: x = 2;<-1> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 2; --->
{
stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with var auto: x = 2;<1>(2,) --->
{
stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto: x --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto with auto: x<1>(auto,) --->
{
stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto: x with var auto: x = 2;<2>(2,auto: x,) --->
pattern_match(auto: x, 2)
{
stack: main{while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... ... --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x == 0)<1>(2,) --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(2,0,) --->
{
stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value false with (! (x == 0))<1>(false,) --->
{
stack: main{true<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value true with while ((! (x == 0)))
... <1>(true,) --->
{
stack: main{{
...
}
<-1> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{x = (x - 1); ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt x = (x - 1); ... --->
{
stack: main{x = (x - 1);<-1> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x - 1)<1>(2,) --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(2,1,) --->
{
stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
{
stack: main{continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt continue; ... --->
{
stack: main{continue;<-1> :: x = (x + 1);<-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt continue; --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x == 0)<1>(1,) --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(1,0,) --->
{
stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value false with (! (x == 0))<1>(false,) --->
{
stack: main{true<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value true with while ((! (x == 0)))
... <1>(true,) --->
{
stack: main{{
...
}
<-1> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{x = (x - 1); ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt x = (x - 1); ... --->
{
stack: main{x = (x - 1);<-1> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
{
stack: main{continue; ... <-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt continue; ... --->
{
stack: main{continue;<-1> :: x = (x + 1);<-1> :: {
...
}
<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt continue; --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<1>(0,) --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(0,0,) --->
{
stack: main{true<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value true with (! (x == 0))<1>(true,) --->
{
stack: main{false<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value false with while ((! (x == 0)))
... <1>(false,) --->
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!0,
env: main: fun<main>,
}
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
fn f(Int: x) -> Int {
return x - 1;
}
fn main() -> Int {
return f(1);
}
+19
View File
@@ -0,0 +1,19 @@
********** source program **********
fn f Int: x -> Int {
return (x - 1);
}
fn main () -> Int {
return f(0 = 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
10: type error in call
expected: Int
actual: Tuple(0 = Int)
+18
View File
@@ -0,0 +1,18 @@
// 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
// This tests the call-by-value aspect of parameter passing.
// This makes sure that when the value in `x` dies,
// it does not cause the value in `a` to also die.
fn f(Int: x) -> Int {
return 0;
}
fn main() -> Int {
var Int: a = 0; var Int: b = 1;
f(a);
b = a;
return b;
}
+25
View File
@@ -0,0 +1,25 @@
********** source program **********
fn f Int: x -> Int {
return 0;
}
fn main () -> Int {
var Int: a = 0;
var Int: b = 1;
f(0 = a);
b = a;
return b;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
15: type error in call
expected: Int
actual: Tuple(0 = Int)
+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 multiple arguments
fn f(Int: x, Int: y) -> Int {
return x + y;
}
fn main() -> Int {
return f(2,3) - 5;
}
+211
View File
@@ -0,0 +1,211 @@
********** source program **********
fn f (0 = Int: x, 1 = Int: y) -> Int {
return (x + y);
}
fn main () -> Int {
return (f(0 = 2, 1 = 3) - 5);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn f (0 = Int: x, 1 = Int: y) -> Int {
return (x + y);
}
fn main () -> Int {
return (f(0 = 2, 1 = 3) - 5);
}
********** starting execution **********
********** initializing globals **********
--- step exp (0 = Int: x, 1 = Int: y) --->
--- step exp Int: x --->
--- step exp Int --->
--- handle value Int with Int: x<1>(Int,) --->
--- handle value Int: x with (0 = Int: x, 1 = Int: y)<1>(Int: x,) --->
--- step exp Int: y --->
--- step exp Int --->
--- handle value Int with Int: y<1>(Int,) --->
--- handle value Int: y with (0 = Int: x, 1 = Int: y)<2>(Int: x,Int: y,) --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return (f(0 = 2, 1 = 3) - 5);<-1>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step stmt return (f(0 = 2, 1 = 3) - 5); --->
{
stack: main{(f(0 = 2, 1 = 3) - 5)<-1> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp (f(0 = 2, 1 = 3) - 5) --->
{
stack: main{f(0 = 2, 1 = 3)<-1> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp f(0 = 2, 1 = 3) --->
{
stack: main{f<-1> :: f(0 = 2, 1 = 3)<0> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp f --->
{
stack: main{fun<f><-1> :: f(0 = 2, 1 = 3)<0> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value fun<f> with f(0 = 2, 1 = 3)<1>(fun<f>,) --->
{
stack: main{(0 = 2, 1 = 3)<-1> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp (0 = 2, 1 = 3) --->
{
stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value 2 with (0 = 2, 1 = 3)<1>(2,) --->
{
stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value 3 with (0 = 2, 1 = 3)<2>(2,3,) --->
{
stack: main{(0 = 2@4, 1 = 3@5)<-1> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3,
env: main: fun<main>, f: fun<f>,
}
--- handle value (0 = 2@4, 1 = 3@5) with f(0 = 2, 1 = 3)<2>(fun<f>,(0 = 2@4, 1 = 3@5),) --->
pattern_match((0 = Int: x@0, 1 = Int: y@1), (0 = 2@4, 1 = 3@5))
pattern_match(Int: x, 2)
pattern_match(Int: y, 3)
{
stack: f{return (x + y);<-1>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- step stmt return (x + y); --->
{
stack: f{(x + y)<-1> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- step exp (x + y) --->
{
stack: f{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- step exp x --->
{
stack: f{2<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- handle value 2 with (x + y)<1>(2,) --->
{
stack: f{y<-1> :: (x + y)<1>(2,) :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- step exp y --->
{
stack: f{3<-1> :: (x + y)<1>(2,) :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- handle value 3 with (x + y)<2>(2,3,) --->
{
stack: f{5<-1> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3,
env: y: 3, x: 2, main: fun<main>, f: fun<f>,
}
--- handle value 5 with return (x + y);<1>(5,) --->
{
stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3,
env: main: fun<main>, f: fun<f>,
}
--- handle value 5 with (f(0 = 2, 1 = 3) - 5)<1>(5,) --->
{
stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<1>(5,) :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3,
env: main: fun<main>, f: fun<f>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<1>(5,) :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3,
env: main: fun<main>, f: fun<f>,
}
--- handle value 5 with (f(0 = 2, 1 = 3) - 5)<2>(5,5,) --->
{
stack: main{0<-1> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3,
env: main: fun<main>, f: fun<f>,
}
--- handle value 0 with return (f(0 = 2, 1 = 3) - 5);<1>(0,) --->
{
stack: top{0<-1>}
heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3,
env: main: fun<main>, f: fun<f>,
}
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 empty parameters and return type
fn f() { }
fn main() -> Int {
f();
return 0;
}
+148
View File
@@ -0,0 +1,148 @@
********** source program **********
fn f () -> ();
fn main () -> Int {
f();
return 0;
}
********** type checking **********
--- step exp () --->
--- step exp Int --->
--- step exp () --->
--- step exp Int --->
********** type checking complete **********
fn f () -> () {
return ();
}
fn main () -> Int {
f();
return 0;
}
********** starting execution **********
********** initializing globals **********
--- step exp () --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{f(); ... <-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step stmt f(); ... --->
{
stack: main{f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step stmt f(); --->
{
stack: main{f()<-1> :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp f() --->
{
stack: main{f<-1> :: f()<0> :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp f --->
{
stack: main{fun<f><-1> :: f()<0> :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value fun<f> with f()<1>(fun<f>,) --->
{
stack: main{()<-1> :: f()<1>(fun<f>,) :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp () --->
{
stack: main{()<-1> :: f()<1>(fun<f>,) :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value () with f()<2>(fun<f>,(),) --->
pattern_match((), ())
{
stack: f{return ();<-1>} :: main{f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step stmt return (); --->
{
stack: f{()<-1> :: return ();<0>} :: main{f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp () --->
{
stack: f{()<-1> :: return ();<0>} :: main{f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value () with return ();<1>((),) --->
{
stack: main{()<-1> :: f();<-1> :: return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value () with f();<0>((),) --->
{
stack: main{return 0;<-1>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step stmt return 0; --->
{
stack: main{0<-1> :: return 0;<0>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: return 0;<0>} :: top{}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
--- handle value 0 with return 0;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<f>, fun<main>,
env: main: fun<main>, f: fun<f>,
}
result: 0
+9
View File
@@ -0,0 +1,9 @@
// 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 add(Int: x, Int: y) => x + y;
fn main() -> Int {
return add(1, 2) - 3;
}
+214
View File
@@ -0,0 +1,214 @@
********** source program **********
fn add (0 = Int: x, 1 = Int: y) -> auto {
return (x + y);
}
fn main () -> Int {
return (add(0 = 1, 1 = 2) - 3);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp Int --->
********** type checking complete **********
fn add (0 = Int: x, 1 = Int: y) -> Int {
return (x + y);
}
fn main () -> Int {
return (add(0 = 1, 1 = 2) - 3);
}
********** starting execution **********
********** initializing globals **********
--- step exp (0 = Int: x, 1 = Int: y) --->
--- step exp Int: x --->
--- step exp Int --->
--- handle value Int with Int: x<1>(Int,) --->
--- handle value Int: x with (0 = Int: x, 1 = Int: y)<1>(Int: x,) --->
--- step exp Int: y --->
--- step exp Int --->
--- handle value Int with Int: y<1>(Int,) --->
--- handle value Int: y with (0 = Int: x, 1 = Int: y)<2>(Int: x,Int: y,) --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return (add(0 = 1, 1 = 2) - 3);<-1>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step stmt return (add(0 = 1, 1 = 2) - 3); --->
{
stack: main{(add(0 = 1, 1 = 2) - 3)<-1> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp (add(0 = 1, 1 = 2) - 3) --->
{
stack: main{add(0 = 1, 1 = 2)<-1> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp add(0 = 1, 1 = 2) --->
{
stack: main{add<-1> :: add(0 = 1, 1 = 2)<0> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp add --->
{
stack: main{fun<add><-1> :: add(0 = 1, 1 = 2)<0> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- handle value fun<add> with add(0 = 1, 1 = 2)<1>(fun<add>,) --->
{
stack: main{(0 = 1, 1 = 2)<-1> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp (0 = 1, 1 = 2) --->
{
stack: main{1<-1> :: (0 = 1, 1 = 2)<0> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (0 = 1, 1 = 2)<0> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- handle value 1 with (0 = 1, 1 = 2)<1>(1,) --->
{
stack: main{2<-1> :: (0 = 1, 1 = 2)<1>(1,) :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (0 = 1, 1 = 2)<1>(1,) :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>,
env: main: fun<main>, add: fun<add>,
}
--- handle value 2 with (0 = 1, 1 = 2)<2>(1,2,) --->
{
stack: main{(0 = 1@4, 1 = 2@5)<-1> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2,
env: main: fun<main>, add: fun<add>,
}
--- handle value (0 = 1@4, 1 = 2@5) with add(0 = 1, 1 = 2)<2>(fun<add>,(0 = 1@4, 1 = 2@5),) --->
pattern_match((0 = Int: x@0, 1 = Int: y@1), (0 = 1@4, 1 = 2@5))
pattern_match(Int: x, 1)
pattern_match(Int: y, 2)
{
stack: add{return (x + y);<-1>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- step stmt return (x + y); --->
{
stack: add{(x + y)<-1> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- step exp (x + y) --->
{
stack: add{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- step exp x --->
{
stack: add{1<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- handle value 1 with (x + y)<1>(1,) --->
{
stack: add{y<-1> :: (x + y)<1>(1,) :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- step exp y --->
{
stack: add{2<-1> :: (x + y)<1>(1,) :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- handle value 2 with (x + y)<2>(1,2,) --->
{
stack: add{3<-1> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2,
env: y: 2, x: 1, main: fun<main>, add: fun<add>,
}
--- handle value 3 with return (x + y);<1>(3,) --->
{
stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2,
env: main: fun<main>, add: fun<add>,
}
--- handle value 3 with (add(0 = 1, 1 = 2) - 3)<1>(3,) --->
{
stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<1>(3,) :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2,
env: main: fun<main>, add: fun<add>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<1>(3,) :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2,
env: main: fun<main>, add: fun<add>,
}
--- handle value 3 with (add(0 = 1, 1 = 2) - 3)<2>(3,3,) --->
{
stack: main{0<-1> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2,
env: main: fun<main>, add: fun<add>,
}
--- handle value 0 with return (add(0 = 1, 1 = 2) - 3);<1>(0,) --->
{
stack: top{0<-1>}
heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2,
env: main: fun<main>, add: fun<add>,
}
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
fn f(Int: x, Int: y) -> Int { return x + y; }
fn main() -> Int {
var (Int, Int): xy = (1, 2);
// should fail to type-check
return f(xy);
}
+27
View File
@@ -0,0 +1,27 @@
********** source program **********
fn f (0 = Int: x, 1 = Int: y) -> Int {
return (x + y);
}
fn main () -> Int {
var (0 = Int, 1 = Int): xy = (0 = 1, 1 = 2);
return f(0 = xy);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp (0 = Int, 1 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
10: type error in call
expected: Tuple(0 = Int, 1 = Int)
actual: Tuple(0 = Tuple(0 = Int, 1 = Int))
+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
fn f(Int: x) -> Int {
if (x == 0)
return x;
else
return f(x - 1);
}
fn main() -> Int {
return f(2);
}
+21
View File
@@ -0,0 +1,21 @@
********** source program **********
fn f Int: x -> Int {
if ((x == 0))
return x;
else
return f(0 = (x - 1));
}
fn main () -> Int {
return f(0 = 2);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
9: type error in call
expected: Int
actual: Tuple(0 = Int)
+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
fn add1(Int: x) -> Int {
return x + 1;
}
fn main() -> Int {
var fnty(Int)->Int: f = add1;
return f(-1);
}
+25
View File
@@ -0,0 +1,25 @@
********** source program **********
fn add1 Int: x -> Int {
return (x + 1);
}
fn main () -> Int {
var fn Int -> Int: f = add1;
return f(0 = (- 1));
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp fn Int -> Int --->
--- step exp Int --->
--- handle value Int with fn Int -> Int<1>(Int,) --->
--- step exp Int --->
--- handle value Int with fn Int -> Int<2>(Int,Int,) --->
11: type error in call
expected: Int
actual: Tuple(0 = Int)
+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
fn main() -> Int {
var auto: t = 5;
match (t) {
case 5 =>
return 0;
default =>
return 1;
}
}
+175
View File
@@ -0,0 +1,175 @@
********** source program **********
fn main () -> Int {
var auto: t = 5;
match (t) {
case 5 =>
return 0;
case auto: _ =>
return 1;
}
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: t = 5;
match (t) {
case 5 =>
return 0;
case auto: _ =>
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{var auto: t = 5; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = 5; ... --->
{
stack: main{var auto: t = 5;<-1> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = 5; --->
{
stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 5 with var auto: t = 5;<1>(5,) --->
{
stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto: t --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto with auto: t<1>(auto,) --->
{
stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto: t with var auto: t = 5;<2>(5,auto: t,) --->
pattern_match(auto: t, 5)
{
stack: main{match (t) {...}<-1>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step stmt match (t) {...} --->
{
stack: main{t<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp t --->
{
stack: main{5<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 5 with match (t) {...}<1>(5,) --->
{
stack: main{5<-1> :: match (t) {...}<1>(5,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: match (t) {...}<1>(5,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 5 with match (t) {...}<2>(5,5,) --->
pattern_match(5, 5)
{
stack: main{return 0;<-1> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step stmt return 0; --->
{
stack: main{0<-1> :: return 0;<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: return 0;<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 0 with return 0;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 5,
env: main: fun<main>,
}
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
fn main() -> Int {
var auto: t = 5;
match (t) {
case 3 =>
return -1;
case 4 =>
return -1;
default =>
return 0;
}
}
+217
View File
@@ -0,0 +1,217 @@
********** source program **********
fn main () -> Int {
var auto: t = 5;
match (t) {
case 3 =>
return (- 1);
case 4 =>
return (- 1);
case auto: _ =>
return 0;
}
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: t = 5;
match (t) {
case 3 =>
return (- 1);
case 4 =>
return (- 1);
case auto: _ =>
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{var auto: t = 5; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = 5; ... --->
{
stack: main{var auto: t = 5;<-1> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = 5; --->
{
stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 5 with var auto: t = 5;<1>(5,) --->
{
stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto: t --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto with auto: t<1>(auto,) --->
{
stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto: t with var auto: t = 5;<2>(5,auto: t,) --->
pattern_match(auto: t, 5)
{
stack: main{match (t) {...}<-1>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step stmt match (t) {...} --->
{
stack: main{t<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp t --->
{
stack: main{5<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 5 with match (t) {...}<1>(5,) --->
{
stack: main{3<-1> :: match (t) {...}<1>(5,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: match (t) {...}<1>(5,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 3 with match (t) {...}<2>(5,3,) --->
pattern_match(3, 5)
{
stack: main{4<-1> :: match (t) {...}<3>(5,3,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp 4 --->
{
stack: main{4<-1> :: match (t) {...}<3>(5,3,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value 4 with match (t) {...}<4>(5,3,4,) --->
pattern_match(4, 5)
{
stack: main{auto: _<-1> :: match (t) {...}<5>(5,3,4,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp auto: _ --->
{
stack: main{auto<-1> :: auto: _<0> :: match (t) {...}<5>(5,3,4,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: _<0> :: match (t) {...}<5>(5,3,4,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value auto with auto: _<1>(auto,) --->
{
stack: main{auto: _<-1> :: match (t) {...}<5>(5,3,4,)} :: top{}
heap: fun<main>, 5,
env: t: 5, main: fun<main>,
}
--- handle value auto: _ with match (t) {...}<6>(5,3,4,auto: _,) --->
pattern_match(auto: _, 5)
{
stack: main{return 0;<-1> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 5,
env: _: 5, t: 5, main: fun<main>,
}
--- step stmt return 0; --->
{
stack: main{0<-1> :: return 0;<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 5,
env: _: 5, t: 5, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: return 0;<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 5,
env: _: 5, t: 5, main: fun<main>,
}
--- handle value 0 with return 0;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 5, !!5,
env: main: fun<main>,
}
result: 0
+21
View File
@@ -0,0 +1,21 @@
// 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 {
var auto: t = fnty (Int,Int);
var Int: x = 0;
// match (t) {
// case fnty(Int: x, Int: y): z =>
// x = x - 1;
// }
match (t) {
case fnty(Int,Int): z =>
x = x + 1;
}
match (t) {
case fnty(Type: a,Type: b) =>
x = x - 1;
}
return x;
}
+653
View File
@@ -0,0 +1,653 @@
********** source program **********
fn main () -> Int {
var auto: t = fn (0 = Int, 1 = Int) -> ();
var Int: x = 0;
match (t) {
case fn (0 = Int, 1 = Int) -> (): z =>
x = (x + 1);
}
match (t) {
case fn (0 = Type: a, 1 = Type: b) -> () =>
x = (x - 1);
}
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp (0 = Int, 1 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
--- step exp () --->
--- step exp auto --->
--- step exp Int --->
--- step exp fn (0 = Int, 1 = Int) -> () --->
--- step exp (0 = Int, 1 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
--- handle value (0 = Int@2, 1 = Int@3) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@2, 1 = Int@3),) --->
--- step exp () --->
--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@2, 1 = Int@3),(),) --->
--- step exp Type --->
--- step exp Type --->
********** type checking complete **********
fn main () -> Int {
var auto: t = fn (0 = Int, 1 = Int) -> ();
var Int: x = 0;
match (t) {
case fn (0 = Int, 1 = Int) -> (): z =>
x = (x + 1);
}
match (t) {
case fn (0 = Type: a, 1 = Type: b) -> () =>
x = (x - 1);
}
return x;
}
********** 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{var auto: t = fn (0 = Int, 1 = Int) -> (); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = fn (0 = Int, 1 = Int) -> (); ... --->
{
stack: main{var auto: t = fn (0 = Int, 1 = Int) -> ();<-1> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = fn (0 = Int, 1 = Int) -> (); --->
{
stack: main{fn (0 = Int, 1 = Int) -> ()<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp fn (0 = Int, 1 = Int) -> () --->
{
stack: main{(0 = Int, 1 = Int)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp (0 = Int, 1 = Int) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
{
stack: main{(0 = Int@1, 1 = Int@2)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- handle value (0 = Int@1, 1 = Int@2) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) --->
{
stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- step exp () --->
{
stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@1, 1 = Int@2),(),) --->
{
stack: main{fn (0 = Int@1, 1 = Int@2) -> ()<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- handle value fn (0 = Int@1, 1 = Int@2) -> () with var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) --->
{
stack: main{auto: t<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- step exp auto: t --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- handle value auto with auto: t<1>(auto,) --->
{
stack: main{auto: t<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int,
env: main: fun<main>,
}
--- handle value auto: t with var auto: t = fn (0 = Int, 1 = Int) -> ();<2>(fn (0 = Int@1, 1 = Int@2) -> (),auto: t,) --->
pattern_match(auto: t, fn (0 = Int@1, 1 = Int@2) -> ())
{
stack: main{var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt var Int: x = 0; ... --->
{
stack: main{var Int: x = 0;<-1> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt var Int: x = 0; --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 0 with var Int: x = 0;<1>(0,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (),
env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
pattern_match(Int: x, 0)
{
stack: main{match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt match (t) {...} ... --->
{
stack: main{match (t) {...}<-1> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt match (t) {...} --->
{
stack: main{t<-1> :: match (t) {...}<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp t --->
{
stack: main{fn (0 = Int@3, 1 = Int@4) -> ()<-1> :: match (t) {...}<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value fn (0 = Int@3, 1 = Int@4) -> () with match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) --->
{
stack: main{fn (0 = Int, 1 = Int) -> (): z<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp fn (0 = Int, 1 = Int) -> (): z --->
{
stack: main{fn (0 = Int, 1 = Int) -> ()<-1> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp fn (0 = Int, 1 = Int) -> () --->
{
stack: main{(0 = Int, 1 = Int)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp (0 = Int, 1 = Int) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
{
stack: main{(0 = Int@7, 1 = Int@8)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value (0 = Int@7, 1 = Int@8) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) --->
{
stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp () --->
{
stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@7, 1 = Int@8),(),) --->
{
stack: main{fn (0 = Int@7, 1 = Int@8) -> ()<-1> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value fn (0 = Int@7, 1 = Int@8) -> () with fn (0 = Int, 1 = Int) -> (): z<1>(fn (0 = Int@7, 1 = Int@8) -> (),) --->
{
stack: main{fn (0 = Int@7, 1 = Int@8) -> (): z<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value fn (0 = Int@7, 1 = Int@8) -> (): z with match (t) {...}<2>(fn (0 = Int@3, 1 = Int@4) -> (),fn (0 = Int@7, 1 = Int@8) -> (): z,) --->
pattern_match(fn (0 = Int@7, 1 = Int@8) -> (): z, fn (0 = Int@3, 1 = Int@4) -> ())
{
stack: main{x = (x + 1);<-1> :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt x = (x + 1); --->
{
stack: main{x<-1> :: x = (x + 1);<0> :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<6><-1> :: x = (x + 1);<0> :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value ptr<6> with x = (x + 1);<1>(ptr<6>,) --->
{
stack: main{(x + 1)<-1> :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp (x + 1) --->
{
stack: main{x<-1> :: (x + 1)<0> :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: (x + 1)<0> :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 0 with (x + 1)<1>(0,) --->
{
stack: main{1<-1> :: (x + 1)<1>(0,) :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x + 1)<1>(0,) :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 1 with (x + 1)<2>(0,1,) --->
{
stack: main{1<-1> :: x = (x + 1);<1>(ptr<6>,) :: {
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 1 with x = (x + 1);<2>(ptr<6>,1,) --->
{
stack: main{{
...
}
<0> :: match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (),
env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{match (t) {...} ... <-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt match (t) {...} ... --->
{
stack: main{match (t) {...}<-1> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt match (t) {...} --->
{
stack: main{t<-1> :: match (t) {...}<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp t --->
{
stack: main{fn (0 = Int@3, 1 = Int@4) -> ()<-1> :: match (t) {...}<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value fn (0 = Int@3, 1 = Int@4) -> () with match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) --->
{
stack: main{fn (0 = Type: a, 1 = Type: b) -> ()<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp fn (0 = Type: a, 1 = Type: b) -> () --->
{
stack: main{(0 = Type: a, 1 = Type: b)<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp (0 = Type: a, 1 = Type: b) --->
{
stack: main{Type: a<-1> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Type: a --->
{
stack: main{Type<-1> :: Type: a<0> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Type --->
{
stack: main{Type<-1> :: Type: a<0> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Type with Type: a<1>(Type,) --->
{
stack: main{Type: a<-1> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Type: a with (0 = Type: a, 1 = Type: b)<1>(Type: a,) --->
{
stack: main{Type: b<-1> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Type: b --->
{
stack: main{Type<-1> :: Type: b<0> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp Type --->
{
stack: main{Type<-1> :: Type: b<0> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Type with Type: b<1>(Type,) --->
{
stack: main{Type: b<-1> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (),
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value Type: b with (0 = Type: a, 1 = Type: b)<2>(Type: a,Type: b,) --->
{
stack: main{(0 = Type: a@12, 1 = Type: b@13)<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b,
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value (0 = Type: a@12, 1 = Type: b@13) with fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) --->
{
stack: main{()<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b,
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp () --->
{
stack: main{()<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b,
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value () with fn (0 = Type: a, 1 = Type: b) -> ()<2>((0 = Type: a@12, 1 = Type: b@13),(),) --->
{
stack: main{fn (0 = Type: a@12, 1 = Type: b@13) -> ()<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b,
env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value fn (0 = Type: a@12, 1 = Type: b@13) -> () with match (t) {...}<2>(fn (0 = Int@3, 1 = Int@4) -> (),fn (0 = Type: a@12, 1 = Type: b@13) -> (),) --->
pattern_match(fn (0 = Type: a@12, 1 = Type: b@13) -> (), fn (0 = Int@3, 1 = Int@4) -> ())
pattern_match((0 = Type: a@12, 1 = Type: b@13), (0 = Int@3, 1 = Int@4))
pattern_match(Type: a, Int)
pattern_match(Type: b, Int)
pattern_match((), ())
{
stack: main{x = (x - 1);<-1> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<6><-1> :: x = (x - 1);<0> :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value ptr<6> with x = (x - 1);<1>(ptr<6>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 1 with (x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: x = (x - 1);<1>(ptr<6>,) :: {
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 0 with x = (x - 1);<2>(ptr<6>,0,) --->
{
stack: main{{
...
}
<0> :: return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int,
env: b: Int, a: Int, x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt {
...
}
--->
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int,
env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, Int, Int, Int, Int, !!fn (0 = Int@3, 1 = Int@4) -> (), !!0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int,
env: main: fun<main>,
}
result: 0
+9
View File
@@ -0,0 +1,9 @@
// 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
{
var Int: x = 0;
return x;
}
+124
View File
@@ -0,0 +1,124 @@
********** source program **********
fn main () -> Int {
var Int: x = 0;
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn main () -> Int {
var Int: x = 0;
return x;
}
********** 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{var Int: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 0; ... --->
{
stack: main{var Int: x = 0;<-1> :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 0; --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: var Int: x = 0;<0> :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 0 with var Int: x = 0;<1>(0,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
pattern_match(Int: x, 0)
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!0,
env: main: fun<main>,
}
result: 0
+8
View File
@@ -0,0 +1,8 @@
// 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 {
var (auto: x, auto: y) = (2, 3);
return y - x - 1;
}
+235
View File
@@ -0,0 +1,235 @@
********** source program **********
fn main () -> Int {
var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);
return ((y - x) - 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);
return ((y - x) - 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{var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); ... --->
{
stack: main{var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<-1> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); --->
{
stack: main{(0 = 2, 1 = 3)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp (0 = 2, 1 = 3) --->
{
stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with (0 = 2, 1 = 3)<1>(2,) --->
{
stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 3 with (0 = 2, 1 = 3)<2>(2,3,) --->
{
stack: main{(0 = 2@1, 1 = 3@2)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- handle value (0 = 2@1, 1 = 3@2) with var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) --->
{
stack: main{(0 = auto: x, 1 = auto: y)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- step exp (0 = auto: x, 1 = auto: y) --->
{
stack: main{auto: x<-1> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- step exp auto: x --->
{
stack: main{auto<-1> :: auto: x<0> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: x<0> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- handle value auto with auto: x<1>(auto,) --->
{
stack: main{auto: x<-1> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- handle value auto: x with (0 = auto: x, 1 = auto: y)<1>(auto: x,) --->
{
stack: main{auto: y<-1> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- step exp auto: y --->
{
stack: main{auto<-1> :: auto: y<0> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: y<0> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- handle value auto with auto: y<1>(auto,) --->
{
stack: main{auto: y<-1> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3,
env: main: fun<main>,
}
--- handle value auto: y with (0 = auto: x, 1 = auto: y)<2>(auto: x,auto: y,) --->
{
stack: main{(0 = auto: x@3, 1 = auto: y@4)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y,
env: main: fun<main>,
}
--- handle value (0 = auto: x@3, 1 = auto: y@4) with var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<2>((0 = 2@1, 1 = 3@2),(0 = auto: x@3, 1 = auto: y@4),) --->
pattern_match((0 = auto: x@3, 1 = auto: y@4), (0 = 2@1, 1 = 3@2))
pattern_match(auto: x, 2)
pattern_match(auto: y, 3)
{
stack: main{return ((y - x) - 1);<-1>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step stmt return ((y - x) - 1); --->
{
stack: main{((y - x) - 1)<-1> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step exp ((y - x) - 1) --->
{
stack: main{(y - x)<-1> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step exp (y - x) --->
{
stack: main{y<-1> :: (y - x)<0> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step exp y --->
{
stack: main{3<-1> :: (y - x)<0> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- handle value 3 with (y - x)<1>(3,) --->
{
stack: main{x<-1> :: (y - x)<1>(3,) :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (y - x)<1>(3,) :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- handle value 2 with (y - x)<2>(3,2,) --->
{
stack: main{1<-1> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- handle value 1 with ((y - x) - 1)<1>(1,) --->
{
stack: main{1<-1> :: ((y - x) - 1)<1>(1,) :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: ((y - x) - 1)<1>(1,) :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- handle value 1 with ((y - x) - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: return ((y - x) - 1);<0>} :: top{}
heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3,
env: y: 3, x: 2, main: fun<main>,
}
--- handle value 0 with return ((y - x) - 1);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 2, 3, auto: x, auto: y, !!2, !!3,
env: main: fun<main>,
}
result: 0
+9
View File
@@ -0,0 +1,9 @@
// 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 {
var (.x = Int, .y = Int): t2 = (.y = 5, .x = 2);
t2.y = 3;
return t2.y - t2.x - 1; // 3 - 2 - 1
}
+298
View File
@@ -0,0 +1,298 @@
********** source program **********
fn main () -> Int {
var (x = Int, y = Int): t2 = (y = 5, x = 2);
t2.y = 3;
return ((t2.y - t2.x) - 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp (x = Int, y = Int) --->
--- step exp Int --->
--- handle value Int with (x = Int, y = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (x = Int, y = Int)<2>(Int,Int,) --->
********** type checking complete **********
fn main () -> Int {
var (x = Int, y = Int): t2 = (y = 5, x = 2);
t2.y = 3;
return ((t2.y - t2.x) - 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{var (x = Int, y = Int): t2 = (y = 5, x = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (x = Int, y = Int): t2 = (y = 5, x = 2); ... --->
{
stack: main{var (x = Int, y = Int): t2 = (y = 5, x = 2);<-1> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (x = Int, y = Int): t2 = (y = 5, x = 2); --->
{
stack: main{(y = 5, x = 2)<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp (y = 5, x = 2) --->
{
stack: main{5<-1> :: (y = 5, x = 2)<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (y = 5, x = 2)<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 5 with (y = 5, x = 2)<1>(5,) --->
{
stack: main{2<-1> :: (y = 5, x = 2)<1>(5,) :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (y = 5, x = 2)<1>(5,) :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with (y = 5, x = 2)<2>(5,2,) --->
{
stack: main{(y = 5@1, x = 2@2)<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value (y = 5@1, x = 2@2) with var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) --->
{
stack: main{(x = Int, y = Int): t2<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp (x = Int, y = Int): t2 --->
{
stack: main{(x = Int, y = Int)<-1> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp (x = Int, y = Int) --->
{
stack: main{Int<-1> :: (x = Int, y = Int)<0> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (x = Int, y = Int)<0> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value Int with (x = Int, y = Int)<1>(Int,) --->
{
stack: main{Int<-1> :: (x = Int, y = Int)<1>(Int,) :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (x = Int, y = Int)<1>(Int,) :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value Int with (x = Int, y = Int)<2>(Int,Int,) --->
{
stack: main{(x = Int@3, y = Int@4)<-1> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int,
env: main: fun<main>,
}
--- handle value (x = Int@3, y = Int@4) with (x = Int, y = Int): t2<1>((x = Int@3, y = Int@4),) --->
{
stack: main{(x = Int@3, y = Int@4): t2<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int,
env: main: fun<main>,
}
--- handle value (x = Int@3, y = Int@4): t2 with var (x = Int, y = Int): t2 = (y = 5, x = 2);<2>((y = 5@1, x = 2@2),(x = Int@3, y = Int@4): t2,) --->
pattern_match((x = Int@3, y = Int@4): t2, (y = 5@1, x = 2@2))
{
stack: main{t2.y = 3; ... <-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- step stmt t2.y = 3; ... --->
{
stack: main{t2.y = 3;<-1> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- step stmt t2.y = 3; --->
{
stack: main{t2.y<-1> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- step lvalue t2.y --->
{
stack: main{t2<-1> :: t2.y<0> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- step lvalue t2 --->
{
stack: main{ptr<7><-1> :: t2.y<0> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- handle value ptr<7> with t2.y<1>(ptr<7>,) --->
{
stack: main{ptr<5><-1> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- handle value ptr<5> with t2.y = 3;<1>(ptr<5>,) --->
{
stack: main{3<-1> :: t2.y = 3;<1>(ptr<5>,) :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: t2.y = 3;<1>(ptr<5>,) :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6),
env: t2: (y = 5@5, x = 2@6), main: fun<main>,
}
--- handle value 3 with t2.y = 3;<2>(ptr<5>,3,) --->
{
stack: main{return ((t2.y - t2.x) - 1);<-1>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step stmt return ((t2.y - t2.x) - 1); --->
{
stack: main{((t2.y - t2.x) - 1)<-1> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step exp ((t2.y - t2.x) - 1) --->
{
stack: main{(t2.y - t2.x)<-1> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step exp (t2.y - t2.x) --->
{
stack: main{t2.y<-1> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step exp t2.y --->
{
stack: main{t2<-1> :: t2.y<0> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step lvalue t2 --->
{
stack: main{ptr<7><-1> :: t2.y<0> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value ptr<7> with t2.y<1>(ptr<7>,) --->
{
stack: main{3<-1> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value 3 with (t2.y - t2.x)<1>(3,) --->
{
stack: main{t2.x<-1> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step exp t2.x --->
{
stack: main{t2<-1> :: t2.x<0> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step lvalue t2 --->
{
stack: main{ptr<7><-1> :: t2.x<0> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value ptr<7> with t2.x<1>(ptr<7>,) --->
{
stack: main{2<-1> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value 2 with (t2.y - t2.x)<2>(3,2,) --->
{
stack: main{1<-1> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value 1 with ((t2.y - t2.x) - 1)<1>(1,) --->
{
stack: main{1<-1> :: ((t2.y - t2.x) - 1)<1>(1,) :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: ((t2.y - t2.x) - 1)<1>(1,) :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value 1 with ((t2.y - t2.x) - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6),
env: t2: (y = 3@5, x = 2@6), main: fun<main>,
}
--- handle value 0 with return ((t2.y - t2.x) - 1);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 5, 2, Int, Int, !!3, !!2, !!(y = !!3@5, x = !!2@6),
env: main: fun<main>,
}
result: 0
+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
struct Point {
var Int: x;
var Int: y;
}
fn main() -> Int {
var auto: p = Point(.x = 1, .y = 2);
return p.y - p.x - 1;
}
+256
View File
@@ -0,0 +1,256 @@
********** source program **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
var auto: p = Point(x = 1, y = 2);
return ((p.y - p.x) - 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
********** type checking complete **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
var auto: p = Point(x = 1, y = 2);
return ((p.y - p.x) - 1);
}
********** starting execution **********
********** initializing globals **********
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{var auto: p = Point(x = 1, y = 2); ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p = Point(x = 1, y = 2); ... --->
{
stack: main{var auto: p = Point(x = 1, y = 2);<-1> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p = Point(x = 1, y = 2); --->
{
stack: main{Point(x = 1, y = 2)<-1> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point(x = 1, y = 2) --->
{
stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point --->
{
stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
{
stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp (x = 1, y = 2) --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
{
stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
{
stack: main{Point(x = 1@4, y = 2@5)<-1> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value Point(x = 1@4, y = 2@5) with var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) --->
{
stack: main{auto: p<-1> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- step exp auto: p --->
{
stack: main{auto<-1> :: auto: p<0> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: p<0> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value auto with auto: p<1>(auto,) --->
{
stack: main{auto: p<-1> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value auto: p with var auto: p = Point(x = 1, y = 2);<2>(Point(x = 1@4, y = 2@5),auto: p,) --->
pattern_match(auto: p, Point(x = 1@4, y = 2@5))
{
stack: main{return ((p.y - p.x) - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt return ((p.y - p.x) - 1); --->
{
stack: main{((p.y - p.x) - 1)<-1> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp ((p.y - p.x) - 1) --->
{
stack: main{(p.y - p.x)<-1> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp (p.y - p.x) --->
{
stack: main{p.y<-1> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp p.y --->
{
stack: main{p<-1> :: p.y<0> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step lvalue p --->
{
stack: main{ptr<8><-1> :: p.y<0> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value ptr<8> with p.y<1>(ptr<8>,) --->
{
stack: main{2<-1> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 2 with (p.y - p.x)<1>(2,) --->
{
stack: main{p.x<-1> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp p.x --->
{
stack: main{p<-1> :: p.x<0> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step lvalue p --->
{
stack: main{ptr<8><-1> :: p.x<0> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value ptr<8> with p.x<1>(ptr<8>,) --->
{
stack: main{1<-1> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 1 with (p.y - p.x)<2>(2,1,) --->
{
stack: main{1<-1> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 1 with ((p.y - p.x) - 1)<1>(1,) --->
{
stack: main{1<-1> :: ((p.y - p.x) - 1)<1>(1,) :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: ((p.y - p.x) - 1)<1>(1,) :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 1 with ((p.y - p.x) - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: return ((p.y - p.x) - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 0 with return ((p.y - p.x) - 1);<1>(0,) --->
{
stack: top{0<-1>}
heap: struct Point, fun<main>, 1, 2, 1, 2, !!1, !!2, !!Point!!(x = !!1@6, y = !!2@7),
env: main: fun<main>, Point: struct Point,
}
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
struct Point {
var Int: x;
var Int: y;
}
fn main() -> Int {
var auto: p1 = Point(.x = 1, .y = 2);
var auto: p2 = p1;
p2.x = 3;
return p1.x - 1;
}
+322
View File
@@ -0,0 +1,322 @@
********** source program **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
var auto: p1 = Point(x = 1, y = 2);
var auto: p2 = p1;
p2.x = 3;
return (p1.x - 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
var auto: p1 = Point(x = 1, y = 2);
var auto: p2 = p1;
p2.x = 3;
return (p1.x - 1);
}
********** starting execution **********
********** initializing globals **********
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{var auto: p1 = Point(x = 1, y = 2); ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p1 = Point(x = 1, y = 2); ... --->
{
stack: main{var auto: p1 = Point(x = 1, y = 2);<-1> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p1 = Point(x = 1, y = 2); --->
{
stack: main{Point(x = 1, y = 2)<-1> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point(x = 1, y = 2) --->
{
stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point --->
{
stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
{
stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp (x = 1, y = 2) --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
{
stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
{
stack: main{Point(x = 1@4, y = 2@5)<-1> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value Point(x = 1@4, y = 2@5) with var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) --->
{
stack: main{auto: p1<-1> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- step exp auto: p1 --->
{
stack: main{auto<-1> :: auto: p1<0> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: p1<0> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value auto with auto: p1<1>(auto,) --->
{
stack: main{auto: p1<-1> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value auto: p1 with var auto: p1 = Point(x = 1, y = 2);<2>(Point(x = 1@4, y = 2@5),auto: p1,) --->
pattern_match(auto: p1, Point(x = 1@4, y = 2@5))
{
stack: main{var auto: p2 = p1; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p2 = p1; ... --->
{
stack: main{var auto: p2 = p1;<-1> :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt var auto: p2 = p1; --->
{
stack: main{p1<-1> :: var auto: p2 = p1;<0> :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp p1 --->
{
stack: main{Point(x = 1@6, y = 2@7)<-1> :: var auto: p2 = p1;<0> :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value Point(x = 1@6, y = 2@7) with var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) --->
{
stack: main{auto: p2<-1> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp auto: p2 --->
{
stack: main{auto<-1> :: auto: p2<0> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: p2<0> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value auto with auto: p2<1>(auto,) --->
{
stack: main{auto: p2<-1> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7),
env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value auto: p2 with var auto: p2 = p1;<2>(Point(x = 1@6, y = 2@7),auto: p2,) --->
pattern_match(auto: p2, Point(x = 1@6, y = 2@7))
{
stack: main{p2.x = 3; ... <-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt p2.x = 3; ... --->
{
stack: main{p2.x = 3;<-1> :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt p2.x = 3; --->
{
stack: main{p2.x<-1> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step lvalue p2.x --->
{
stack: main{p2<-1> :: p2.x<0> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step lvalue p2 --->
{
stack: main{ptr<11><-1> :: p2.x<0> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value ptr<11> with p2.x<1>(ptr<11>,) --->
{
stack: main{ptr<9><-1> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value ptr<9> with p2.x = 3;<1>(ptr<9>,) --->
{
stack: main{3<-1> :: p2.x = 3;<1>(ptr<9>,) :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp 3 --->
{
stack: main{3<-1> :: p2.x = 3;<1>(ptr<9>,) :: return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10),
env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 3 with p2.x = 3;<2>(ptr<9>,3,) --->
{
stack: main{return (p1.x - 1);<-1>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step stmt return (p1.x - 1); --->
{
stack: main{(p1.x - 1)<-1> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp (p1.x - 1) --->
{
stack: main{p1.x<-1> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp p1.x --->
{
stack: main{p1<-1> :: p1.x<0> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step lvalue p1 --->
{
stack: main{ptr<8><-1> :: p1.x<0> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value ptr<8> with p1.x<1>(ptr<8>,) --->
{
stack: main{1<-1> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 1 with (p1.x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (p1.x - 1)<1>(1,) :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (p1.x - 1)<1>(1,) :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 1 with (p1.x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: return (p1.x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10),
env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point,
}
--- handle value 0 with return (p1.x - 1);<1>(0,) --->
{
stack: top{0<-1>}
heap: struct Point, fun<main>, 1, 2, 1, 2, !!1, !!2, !!Point!!(x = !!1@6, y = !!2@7), !!3, !!2, !!Point!!(x = !!3@9, y = !!2@10),
env: main: fun<main>, Point: struct Point,
}
result: 0
+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
struct Point {
var Int: x;
var Int: y;
}
fn main() -> Int {
return Point(.x = 1, .y = 2).x - 1;
}
+186
View File
@@ -0,0 +1,186 @@
********** source program **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
return (Point(x = 1, y = 2).x - 1);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
struct Point {
var x : Int;
var y : Int;
}
fn main () -> Int {
return (Point(x = 1, y = 2).x - 1);
}
********** starting execution **********
********** initializing globals **********
--- step exp Int --->
--- step exp Int --->
--- step exp () --->
********** calling main function **********
{
stack: top{main()<-1>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main() --->
{
stack: top{main<-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp main --->
{
stack: top{fun<main><-1> :: main()<0>}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value fun<main> with main()<1>(fun<main>,) --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp () --->
{
stack: top{()<-1> :: main()<1>(fun<main>,)}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value () with main()<2>(fun<main>,(),) --->
pattern_match((), ())
{
stack: main{return (Point(x = 1, y = 2).x - 1);<-1>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step stmt return (Point(x = 1, y = 2).x - 1); --->
{
stack: main{(Point(x = 1, y = 2).x - 1)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp (Point(x = 1, y = 2).x - 1) --->
{
stack: main{Point(x = 1, y = 2).x<-1> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point(x = 1, y = 2).x --->
{
stack: main{Point(x = 1, y = 2)<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step lvalue Point(x = 1, y = 2) --->
{
stack: main{Point(x = 1, y = 2)<-1> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point(x = 1, y = 2) --->
{
stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp Point --->
{
stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
{
stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp (x = 1, y = 2) --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>,
env: main: fun<main>, Point: struct Point,
}
--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
{
stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
{
stack: main{Point(x = 1@4, y = 2@5)<-1> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2,
env: main: fun<main>, Point: struct Point,
}
--- handle value Point(x = 1@4, y = 2@5) with exp=>lval<0>(Point(x = 1@4, y = 2@5),) --->
{
stack: main{ptr<6><-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5),
env: main: fun<main>, Point: struct Point,
}
--- handle value ptr<6> with Point(x = 1, y = 2).x<1>(ptr<6>,) --->
{
stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<0> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5),
env: main: fun<main>, Point: struct Point,
}
--- handle value 1 with (Point(x = 1, y = 2).x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<1>(1,) :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5),
env: main: fun<main>, Point: struct Point,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<1>(1,) :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5),
env: main: fun<main>, Point: struct Point,
}
--- handle value 1 with (Point(x = 1, y = 2).x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5),
env: main: fun<main>, Point: struct Point,
}
--- handle value 0 with delete_tmp(6)<0>(0,) --->
{
stack: main{0<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
heap: struct Point, fun<main>, 1, 2, !!1, !!2, !!Point!!(x = !!1@4, y = !!2@5),
env: main: fun<main>, Point: struct Point,
}
--- handle value 0 with return (Point(x = 1, y = 2).x - 1);<1>(0,) --->
{
stack: top{0<-1>}
heap: struct Point, fun<main>, 1, 2, !!1, !!2, !!Point!!(x = !!1@4, y = !!2@5),
env: main: fun<main>, Point: struct Point,
}
result: 0
+10
View File
@@ -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 {
var Int: x = (1);
var (Int,Int): t2 = (5, 2);
t2[0] = 3;
return t2[0] - t2[1] - x;
}
+389
View File
@@ -0,0 +1,389 @@
********** source program **********
fn main () -> Int {
var Int: x = 1;
var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);
t2[0] = 3;
return ((t2[0] - t2[1]) - x);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp Int --->
--- step exp (0 = Int, 1 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
--- step exp Int --->
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
--- step exp 0 --->
--- step exp 0 --->
--- step exp 1 --->
********** type checking complete **********
fn main () -> Int {
var Int: x = 1;
var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);
t2[0] = 3;
return ((t2[0] - t2[1]) - x);
}
********** 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{var Int: x = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 1; ... --->
{
stack: main{var Int: x = 1;<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var Int: x = 1; --->
{
stack: main{1<-1> :: var Int: x = 1;<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: var Int: x = 1;<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 1 with var Int: x = 1;<1>(1,) --->
{
stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int: x --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int with Int: x<1>(Int,) --->
{
stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value Int: x with var Int: x = 1;<2>(1,Int: x,) --->
pattern_match(Int: x, 1)
{
stack: main{var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... --->
{
stack: main{var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<-1> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); --->
{
stack: main{(0 = 5, 1 = 2)<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (0 = 5, 1 = 2) --->
{
stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 5 with (0 = 5, 1 = 2)<1>(5,) --->
{
stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 2 with (0 = 5, 1 = 2)<2>(5,2,) --->
{
stack: main{(0 = 5@2, 1 = 2@3)<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- handle value (0 = 5@2, 1 = 2@3) with var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) --->
{
stack: main{(0 = Int, 1 = Int): t2<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- step exp (0 = Int, 1 = Int): t2 --->
{
stack: main{(0 = Int, 1 = Int)<-1> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- step exp (0 = Int, 1 = Int) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2,
env: x: 1, main: fun<main>,
}
--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
{
stack: main{(0 = Int@4, 1 = Int@5)<-1> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int,
env: x: 1, main: fun<main>,
}
--- handle value (0 = Int@4, 1 = Int@5) with (0 = Int, 1 = Int): t2<1>((0 = Int@4, 1 = Int@5),) --->
{
stack: main{(0 = Int@4, 1 = Int@5): t2<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int,
env: x: 1, main: fun<main>,
}
--- handle value (0 = Int@4, 1 = Int@5): t2 with var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<2>((0 = 5@2, 1 = 2@3),(0 = Int@4, 1 = Int@5): t2,) --->
pattern_match((0 = Int@4, 1 = Int@5): t2, (0 = 5@2, 1 = 2@3))
{
stack: main{t2[0] = 3; ... <-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step stmt t2[0] = 3; ... --->
{
stack: main{t2[0] = 3;<-1> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step stmt t2[0] = 3; --->
{
stack: main{t2[0]<-1> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step lvalue t2[0] --->
{
stack: main{t2<-1> :: t2[0]<0> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp t2 --->
{
stack: main{(0 = 5@6, 1 = 2@7)<-1> :: t2[0]<0> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value (0 = 5@6, 1 = 2@7) with t2[0]<1>((0 = 5@6, 1 = 2@7),) --->
{
stack: main{0<-1> :: t2[0]<1>((0 = 5@6, 1 = 2@7),) :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: t2[0]<1>((0 = 5@6, 1 = 2@7),) :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 0 with t2[0]<2>((0 = 5@6, 1 = 2@7),0,) --->
{
stack: main{ptr<6><-1> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value ptr<6> with t2[0] = 3;<1>(ptr<6>,) --->
{
stack: main{3<-1> :: t2[0] = 3;<1>(ptr<6>,) :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp 3 --->
{
stack: main{3<-1> :: t2[0] = 3;<1>(ptr<6>,) :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7),
env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 3 with t2[0] = 3;<2>(ptr<6>,3,) --->
{
stack: main{return ((t2[0] - t2[1]) - x);<-1>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step stmt return ((t2[0] - t2[1]) - x); --->
{
stack: main{((t2[0] - t2[1]) - x)<-1> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp ((t2[0] - t2[1]) - x) --->
{
stack: main{(t2[0] - t2[1])<-1> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp (t2[0] - t2[1]) --->
{
stack: main{t2[0]<-1> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp t2[0] --->
{
stack: main{t2<-1> :: t2[0]<0> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp t2 --->
{
stack: main{(0 = 3@6, 1 = 2@7)<-1> :: t2[0]<0> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value (0 = 3@6, 1 = 2@7) with t2[0]<1>((0 = 3@6, 1 = 2@7),) --->
{
stack: main{0<-1> :: t2[0]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: t2[0]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 0 with t2[0]<2>((0 = 3@6, 1 = 2@7),0,) --->
{
stack: main{3<-1> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 3 with (t2[0] - t2[1])<1>(3,) --->
{
stack: main{t2[1]<-1> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp t2[1] --->
{
stack: main{t2<-1> :: t2[1]<0> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp t2 --->
{
stack: main{(0 = 3@6, 1 = 2@7)<-1> :: t2[1]<0> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value (0 = 3@6, 1 = 2@7) with t2[1]<1>((0 = 3@6, 1 = 2@7),) --->
{
stack: main{1<-1> :: t2[1]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: t2[1]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 1 with t2[1]<2>((0 = 3@6, 1 = 2@7),1,) --->
{
stack: main{2<-1> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 2 with (t2[0] - t2[1])<2>(3,2,) --->
{
stack: main{1<-1> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 1 with ((t2[0] - t2[1]) - x)<1>(1,) --->
{
stack: main{x<-1> :: ((t2[0] - t2[1]) - x)<1>(1,) :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: ((t2[0] - t2[1]) - x)<1>(1,) :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 1 with ((t2[0] - t2[1]) - x)<2>(1,1,) --->
{
stack: main{0<-1> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7),
env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>,
}
--- handle value 0 with return ((t2[0] - t2[1]) - x);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!1, 5, 2, Int, Int, !!3, !!2, !!(0 = !!3@6, 1 = !!2@7),
env: main: fun<main>,
}
result: 0
+8
View File
@@ -0,0 +1,8 @@
// 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 {
var (Int,): t = (5,);
return t[0] - 5;
}
+199
View File
@@ -0,0 +1,199 @@
********** source program **********
fn main () -> Int {
var (0 = Int): t = (0 = 5);
return (t[0] - 5);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp (0 = Int) --->
--- step exp Int --->
--- handle value Int with (0 = Int)<1>(Int,) --->
--- step exp 0 --->
********** type checking complete **********
fn main () -> Int {
var (0 = Int): t = (0 = 5);
return (t[0] - 5);
}
********** 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{var (0 = Int): t = (0 = 5); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (0 = Int): t = (0 = 5); ... --->
{
stack: main{var (0 = Int): t = (0 = 5);<-1> :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var (0 = Int): t = (0 = 5); --->
{
stack: main{(0 = 5)<-1> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp (0 = 5) --->
{
stack: main{5<-1> :: (0 = 5)<0> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (0 = 5)<0> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 5 with (0 = 5)<1>(5,) --->
{
stack: main{(0 = 5@1)<-1> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5,
env: main: fun<main>,
}
--- handle value (0 = 5@1) with var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) --->
{
stack: main{(0 = Int): t<-1> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5,
env: main: fun<main>,
}
--- step exp (0 = Int): t --->
{
stack: main{(0 = Int)<-1> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5,
env: main: fun<main>,
}
--- step exp (0 = Int) --->
{
stack: main{Int<-1> :: (0 = Int)<0> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5,
env: main: fun<main>,
}
--- step exp Int --->
{
stack: main{Int<-1> :: (0 = Int)<0> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5,
env: main: fun<main>,
}
--- handle value Int with (0 = Int)<1>(Int,) --->
{
stack: main{(0 = Int@2)<-1> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5, Int,
env: main: fun<main>,
}
--- handle value (0 = Int@2) with (0 = Int): t<1>((0 = Int@2),) --->
{
stack: main{(0 = Int@2): t<-1> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5, Int,
env: main: fun<main>,
}
--- handle value (0 = Int@2): t with var (0 = Int): t = (0 = 5);<2>((0 = 5@1),(0 = Int@2): t,) --->
pattern_match((0 = Int@2): t, (0 = 5@1))
{
stack: main{return (t[0] - 5);<-1>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step stmt return (t[0] - 5); --->
{
stack: main{(t[0] - 5)<-1> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step exp (t[0] - 5) --->
{
stack: main{t[0]<-1> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step exp t[0] --->
{
stack: main{t<-1> :: t[0]<0> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step exp t --->
{
stack: main{(0 = 5@3)<-1> :: t[0]<0> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- handle value (0 = 5@3) with t[0]<1>((0 = 5@3),) --->
{
stack: main{0<-1> :: t[0]<1>((0 = 5@3),) :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: t[0]<1>((0 = 5@3),) :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- handle value 0 with t[0]<2>((0 = 5@3),0,) --->
{
stack: main{5<-1> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- handle value 5 with (t[0] - 5)<1>(5,) --->
{
stack: main{5<-1> :: (t[0] - 5)<1>(5,) :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (t[0] - 5)<1>(5,) :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- handle value 5 with (t[0] - 5)<2>(5,5,) --->
{
stack: main{0<-1> :: return (t[0] - 5);<0>} :: top{}
heap: fun<main>, 5, Int, 5, (0 = 5@3),
env: t: (0 = 5@3), main: fun<main>,
}
--- handle value 0 with return (t[0] - 5);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 5, Int, !!5, !!(0 = !!5@3),
env: main: fun<main>,
}
result: 0
+10
View File
@@ -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 {
var auto: x = 0;
var auto: y = 1;
(x, y) = (5, -5);
return x + y;
}
+298
View File
@@ -0,0 +1,298 @@
********** source program **********
fn main () -> Int {
var auto: x = 0;
var auto: y = 1;
(0 = x, 1 = y) = (0 = 5, 1 = (- 5));
return (x + y);
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: x = 0;
var auto: y = 1;
(0 = x, 1 = y) = (0 = 5, 1 = (- 5));
return (x + y);
}
********** 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{var auto: x = 0; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 0; ... --->
{
stack: main{var auto: x = 0;<-1> :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 0; --->
{
stack: main{0<-1> :: var auto: x = 0;<0> :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: var auto: x = 0;<0> :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 0 with var auto: x = 0;<1>(0,) --->
{
stack: main{auto: x<-1> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto: x --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto with auto: x<1>(auto,) --->
{
stack: main{auto: x<-1> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto: x with var auto: x = 0;<2>(0,auto: x,) --->
pattern_match(auto: x, 0)
{
stack: main{var auto: y = 1; ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt var auto: y = 1; ... --->
{
stack: main{var auto: y = 1;<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt var auto: y = 1; --->
{
stack: main{1<-1> :: var auto: y = 1;<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: var auto: y = 1;<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 1 with var auto: y = 1;<1>(1,) --->
{
stack: main{auto: y<-1> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp auto: y --->
{
stack: main{auto<-1> :: auto: y<0> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: y<0> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value auto with auto: y<1>(auto,) --->
{
stack: main{auto: y<-1> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value auto: y with var auto: y = 1;<2>(1,auto: y,) --->
pattern_match(auto: y, 1)
{
stack: main{(0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- step stmt (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... --->
{
stack: main{(0 = x, 1 = y) = (0 = 5, 1 = (- 5));<-1> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- step stmt (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); --->
{
stack: main{(0 = x, 1 = y)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- step lvalue (0 = x, 1 = y) --->
{
stack: main{x<-1> :: (0 = x, 1 = y)<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: (0 = x, 1 = y)<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value ptr<1> with (0 = x, 1 = y)<1>(ptr<1>,) --->
{
stack: main{y<-1> :: (0 = x, 1 = y)<1>(ptr<1>,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- step lvalue y --->
{
stack: main{ptr<2><-1> :: (0 = x, 1 = y)<1>(ptr<1>,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value ptr<2> with (0 = x, 1 = y)<2>(ptr<1>,ptr<2>,) --->
{
stack: main{(0 = ptr<1>@3, 1 = ptr<2>@4)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value (0 = ptr<1>@3, 1 = ptr<2>@4) with (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) --->
{
stack: main{(0 = 5, 1 = (- 5))<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- step exp (0 = 5, 1 = (- 5)) --->
{
stack: main{5<-1> :: (0 = 5, 1 = (- 5))<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (0 = 5, 1 = (- 5))<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value 5 with (0 = 5, 1 = (- 5))<1>(5,) --->
{
stack: main{(- 5)<-1> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- step exp (- 5) --->
{
stack: main{5<-1> :: (- 5)<0> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (- 5)<0> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value 5 with (- 5)<1>(5,) --->
{
stack: main{-5<-1> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value -5 with (0 = 5, 1 = (- 5))<2>(5,-5,) --->
{
stack: main{(0 = 5@5, 1 = -5@6)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 5, -5,
env: y: 1, x: 0, main: fun<main>,
}
--- handle value (0 = 5@5, 1 = -5@6) with (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<2>((0 = ptr<1>@3, 1 = ptr<2>@4),(0 = 5@5, 1 = -5@6),) --->
{
stack: main{return (x + y);<-1>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- step stmt return (x + y); --->
{
stack: main{(x + y)<-1> :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- step exp (x + y) --->
{
stack: main{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- step exp x --->
{
stack: main{5<-1> :: (x + y)<0> :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- handle value 5 with (x + y)<1>(5,) --->
{
stack: main{y<-1> :: (x + y)<1>(5,) :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- step exp y --->
{
stack: main{-5<-1> :: (x + y)<1>(5,) :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- handle value -5 with (x + y)<2>(5,-5,) --->
{
stack: main{0<-1> :: return (x + y);<0>} :: top{}
heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5,
env: y: -5, x: 5, main: fun<main>,
}
--- handle value 0 with return (x + y);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!5, !!-5, ptr<1>, ptr<2>, !!5, !!-5,
env: main: fun<main>,
}
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
fn main() -> Int {
var auto: t = (5, 2);
match (t) {
case (auto: a, auto: b) =>
return a + b - 7;
}
}
+318
View File
@@ -0,0 +1,318 @@
********** source program **********
fn main () -> Int {
var auto: t = (0 = 5, 1 = 2);
match (t) {
case (0 = auto: a, 1 = auto: b) =>
return ((a + b) - 7);
}
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
--- step exp auto --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: t = (0 = 5, 1 = 2);
match (t) {
case (0 = auto: a, 1 = auto: b) =>
return ((a + b) - 7);
}
}
********** 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{var auto: t = (0 = 5, 1 = 2); ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = (0 = 5, 1 = 2); ... --->
{
stack: main{var auto: t = (0 = 5, 1 = 2);<-1> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: t = (0 = 5, 1 = 2); --->
{
stack: main{(0 = 5, 1 = 2)<-1> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp (0 = 5, 1 = 2) --->
{
stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 5 --->
{
stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 5 with (0 = 5, 1 = 2)<1>(5,) --->
{
stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with (0 = 5, 1 = 2)<2>(5,2,) --->
{
stack: main{(0 = 5@1, 1 = 2@2)<-1> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value (0 = 5@1, 1 = 2@2) with var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) --->
{
stack: main{auto: t<-1> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp auto: t --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: t<0> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value auto with auto: t<1>(auto,) --->
{
stack: main{auto: t<-1> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2,
env: main: fun<main>,
}
--- handle value auto: t with var auto: t = (0 = 5, 1 = 2);<2>((0 = 5@1, 1 = 2@2),auto: t,) --->
pattern_match(auto: t, (0 = 5@1, 1 = 2@2))
{
stack: main{match (t) {...}<-1>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step stmt match (t) {...} --->
{
stack: main{t<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp t --->
{
stack: main{(0 = 5@3, 1 = 2@4)<-1> :: match (t) {...}<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value (0 = 5@3, 1 = 2@4) with match (t) {...}<1>((0 = 5@3, 1 = 2@4),) --->
{
stack: main{(0 = auto: a, 1 = auto: b)<-1> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp (0 = auto: a, 1 = auto: b) --->
{
stack: main{auto: a<-1> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp auto: a --->
{
stack: main{auto<-1> :: auto: a<0> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: a<0> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value auto with auto: a<1>(auto,) --->
{
stack: main{auto: a<-1> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value auto: a with (0 = auto: a, 1 = auto: b)<1>(auto: a,) --->
{
stack: main{auto: b<-1> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp auto: b --->
{
stack: main{auto<-1> :: auto: b<0> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: b<0> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value auto with auto: b<1>(auto,) --->
{
stack: main{auto: b<-1> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4),
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value auto: b with (0 = auto: a, 1 = auto: b)<2>(auto: a,auto: b,) --->
{
stack: main{(0 = auto: a@6, 1 = auto: b@7)<-1> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b,
env: t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value (0 = auto: a@6, 1 = auto: b@7) with match (t) {...}<2>((0 = 5@3, 1 = 2@4),(0 = auto: a@6, 1 = auto: b@7),) --->
pattern_match((0 = auto: a@6, 1 = auto: b@7), (0 = 5@3, 1 = 2@4))
pattern_match(auto: a, 5)
pattern_match(auto: b, 2)
{
stack: main{return ((a + b) - 7);<-1> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step stmt return ((a + b) - 7); --->
{
stack: main{((a + b) - 7)<-1> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp ((a + b) - 7) --->
{
stack: main{(a + b)<-1> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp (a + b) --->
{
stack: main{a<-1> :: (a + b)<0> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp a --->
{
stack: main{5<-1> :: (a + b)<0> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value 5 with (a + b)<1>(5,) --->
{
stack: main{b<-1> :: (a + b)<1>(5,) :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp b --->
{
stack: main{2<-1> :: (a + b)<1>(5,) :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value 2 with (a + b)<2>(5,2,) --->
{
stack: main{7<-1> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value 7 with ((a + b) - 7)<1>(7,) --->
{
stack: main{7<-1> :: ((a + b) - 7)<1>(7,) :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- step exp 7 --->
{
stack: main{7<-1> :: ((a + b) - 7)<1>(7,) :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value 7 with ((a + b) - 7)<2>(7,7,) --->
{
stack: main{0<-1> :: return ((a + b) - 7);<0> :: {
...
}
<0>} :: top{}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2,
env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>,
}
--- handle value 0 with return ((a + b) - 7);<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, !!5, !!2,
env: main: fun<main>,
}
result: 0
+18
View File
@@ -0,0 +1,18 @@
// 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
// The behavior of this program is undefined because it tries to
// access a local variable after its lifetime is over.
fn f() -> Int* {
var int: x;
x = 0;
return &x;
}
fn main() -> int {
var Ptr(int): p;
p = f();
return *p;
}
+1
View File
@@ -0,0 +1 @@
executable_semantics/testdata/undef1.6c:8: syntax error
+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
// Use-after-free.
fun main() -> Int {
var Ptr(int): p;
p = malloc(Int);
*p = 0;
free(p);
return *p;
}
+3
View File
@@ -0,0 +1,3 @@
********** source program **********
********** type checking **********
error, program must contain a function named `main`
+10
View File
@@ -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 {
var auto: x = 2;
while (not (x == 0))
x = x - 1;
return x;
}
+464
View File
@@ -0,0 +1,464 @@
********** source program **********
fn main () -> Int {
var auto: x = 2;
while ((! (x == 0)))
x = (x - 1);
return x;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
--- step exp auto --->
********** type checking complete **********
fn main () -> Int {
var auto: x = 2;
while ((! (x == 0)))
x = (x - 1);
return x;
}
********** 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{var auto: x = 2; ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 2; ... --->
{
stack: main{var auto: x = 2;<-1> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt var auto: x = 2; --->
{
stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 2 --->
{
stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value 2 with var auto: x = 2;<1>(2,) --->
{
stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto: x --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp auto --->
{
stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto with auto: x<1>(auto,) --->
{
stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- handle value auto: x with var auto: x = 2;<2>(2,auto: x,) --->
pattern_match(auto: x, 2)
{
stack: main{while ((! (x == 0)))
... ... <-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... ... --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x == 0)<1>(2,) --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(2,0,) --->
{
stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value false with (! (x == 0))<1>(false,) --->
{
stack: main{true<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value true with while ((! (x == 0)))
... <1>(true,) --->
{
stack: main{x = (x - 1);<-1> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp x --->
{
stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 2 with (x - 1)<1>(2,) --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(2,1,) --->
{
stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 2,
env: x: 2, main: fun<main>,
}
--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x == 0)<1>(1,) --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(1,0,) --->
{
stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value false with (! (x == 0))<1>(false,) --->
{
stack: main{true<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value true with while ((! (x == 0)))
... <1>(true,) --->
{
stack: main{x = (x - 1);<-1> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step stmt x = (x - 1); --->
{
stack: main{x<-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step lvalue x --->
{
stack: main{ptr<1><-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
{
stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp (x - 1) --->
{
stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp x --->
{
stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<1>(1,) --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- step exp 1 --->
{
stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 1 with (x - 1)<2>(1,1,) --->
{
stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 1,
env: x: 1, main: fun<main>,
}
--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
{
stack: main{while ((! (x == 0)))
... <-1> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt while ((! (x == 0)))
... --->
{
stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp (! (x == 0)) --->
{
stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp (x == 0) --->
{
stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<1>(0,) --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with (x == 0)<2>(0,0,) --->
{
stack: main{true<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value true with (! (x == 0))<1>(true,) --->
{
stack: main{false<-1> :: while ((! (x == 0)))
... <0> :: return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value false with while ((! (x == 0)))
... <1>(false,) --->
{
stack: main{return x;<-1>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step stmt return x; --->
{
stack: main{x<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- step exp x --->
{
stack: main{0<-1> :: return x;<0>} :: top{}
heap: fun<main>, 0,
env: x: 0, main: fun<main>,
}
--- handle value 0 with return x;<1>(0,) --->
{
stack: top{0<-1>}
heap: fun<main>, !!0,
env: main: fun<main>,
}
result: 0
+7
View File
@@ -0,0 +1,7 @@
// 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 {
return 0;
}
+72
View File
@@ -0,0 +1,72 @@
********** source program **********
fn main () -> Int {
return 0;
}
********** type checking **********
--- step exp Int --->
--- step exp Int --->
********** type checking complete **********
fn main () -> Int {
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{return 0;<-1>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step stmt return 0; --->
{
stack: main{0<-1> :: return 0;<0>} :: top{}
heap: fun<main>,
env: main: fun<main>,
}
--- step exp 0 --->
{
stack: main{0<-1> :: return 0;<0>} :: 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