mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:10:13 +01:00
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:
@@ -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
@@ -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",
|
||||
],
|
||||
),
|
||||
]),
|
||||
|
||||
@@ -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"])
|
||||
@@ -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
|
||||
)
|
||||
Executable
+36
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
@@ -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.
|
||||
@@ -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"],
|
||||
)
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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; }
|
||||
@@ -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);
|
||||
}
|
||||
;
|
||||
%%
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@
|
||||
executable_semantics/testdata/undef1.6c:8: syntax error
|
||||
+13
@@ -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
@@ -0,0 +1,3 @@
|
||||
********** source program **********
|
||||
********** type checking **********
|
||||
error, program must contain a function named `main`
|
||||
+10
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
Reference in New Issue
Block a user