Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Syntax #162

Merged
merged 59 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b43a9ce
first draft of proposal for basic syntax
jsiek Sep 19, 2020
53b8dd5
rename proposal
jsiek Sep 19, 2020
f048c11
formating
jsiek Sep 19, 2020
86cedc3
fixing typos
jsiek Sep 19, 2020
eed621c
precendence and associativity
jsiek Sep 21, 2020
e26781c
minor edit
jsiek Sep 21, 2020
c8d833e
added abstract syntax
jsiek Sep 22, 2020
974d91a
some revisions based on feedback from meeting today
jsiek Sep 23, 2020
2279899
optional return type
jsiek Sep 23, 2020
42068f7
oops, not optional for function declarations
jsiek Sep 23, 2020
c6daf89
replacing abbreviations with full names
jsiek Sep 24, 2020
556deab
name changes
jsiek Sep 24, 2020
0855d05
Update proposals/p0162.md
jsiek Sep 24, 2020
b02522b
removed = from precedence table
jsiek Sep 24, 2020
43c4b9f
for fun decl, back to optional return type, shorthand for void return
jsiek Sep 25, 2020
28bfaf5
more fiddling with return types
jsiek Sep 26, 2020
3ef030a
change base case of statement_list to empty
jsiek Sep 26, 2020
dd4cf52
added pattern non-terminal
jsiek Sep 27, 2020
34b50f2
added expression style function definitions
jsiek Sep 27, 2020
5f95ac3
change && to and, || to or
jsiek Sep 27, 2020
2cc4f67
change and to have equal precedence
jsiek Sep 27, 2020
e0afba2
updating text to match grammar, fix typo in grammar regarding pattern
jsiek Sep 27, 2020
fa2695c
adding trailing comma thing to tuples
jsiek Sep 27, 2020
dc80cbd
removed 'alt' keyword, not necessary
jsiek Sep 27, 2020
c611253
flipped expression and pattern
jsiek Sep 28, 2020
e780d81
added period for named arguments and documented the reason
jsiek Sep 30, 2020
24c2eac
change alternative syntax to use tuple instead of expression
jsiek Sep 30, 2020
6e8dc8a
comment about abstract syntax
jsiek Sep 30, 2020
097a10d
code block language annotations
jsiek Oct 1, 2020
c1a3e66
added alternative designs, some cleanup for pre-commit
jsiek Oct 1, 2020
c12a1e5
spell checking
jsiek Oct 1, 2020
58106f7
filled out the TOC
jsiek Oct 1, 2020
8472acf
minor edits
jsiek Oct 1, 2020
e1149fe
minor edit
jsiek Oct 1, 2020
5f6ed24
trying to fix pre-commit error
jsiek Oct 1, 2020
edc65bd
changes from pre-commit?
jsiek Oct 7, 2020
9555b53
changes based on meeting today
jsiek Oct 7, 2020
2386f28
describe alternatives regarding methods
jsiek Oct 7, 2020
246da20
more rationale in discussion of alternatives
jsiek Oct 7, 2020
0b6dd7a
addressing comments
jsiek Oct 8, 2020
4d66890
typo fix, added text about next steps
jsiek Oct 21, 2020
5918704
removed *, changed a ! to not
jsiek Oct 22, 2020
c2d963c
Update proposals/p0162.md
jsiek Oct 23, 2020
a76b975
edits from feedback
jsiek Oct 23, 2020
6aa6b6c
Merge branch 'basic-syntax' of https://github.com/jsiek/carbon-lang i…
jsiek Oct 23, 2020
9ca7249
pre-commit
jsiek Oct 23, 2020
df011b3
added second reason for period in field initializer
jsiek Oct 23, 2020
e62dac3
added executable semantics, fixed misunderstanding regarding associat…
jsiek Oct 24, 2020
0e38274
update README
jsiek Oct 24, 2020
49949e8
added a paragraph about tuples and tuple types
jsiek Oct 25, 2020
7292650
Update proposals/p0162.md
jsiek Oct 28, 2020
cb7efb6
addressing comments from josh11b
jsiek Oct 28, 2020
01045a8
Merge branch 'basic-syntax' of https://github.com/jsiek/carbon-lang i…
jsiek Oct 28, 2020
fa8a246
Update executable-semantics/README.md
jsiek Oct 28, 2020
6462c6f
link to implicit parameters in generics proposal
jsiek Oct 28, 2020
535d46f
added non-terminal for designator as per geoffromer's suggestion
jsiek Oct 29, 2020
1036bec
changed handling of tuples in function call and similar places as per…
jsiek Oct 29, 2020
2a81ff4
moving code to separate PR
jsiek Oct 30, 2020
6020b32
resolved merge conflict in proposals/README
jsiek Nov 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions executable-semantics/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
a.out: syntax.l syntax.y ast.h typecheck.h interp.h ast.cc typecheck.cc interp.cc cons_list.h assoc_list.h
bison -d syntax.y
flex syntax.l
bison -v --debug syntax.y -o syntax.tab.cc
g++ -std=c++11 -Wno-deprecated-register -c -g lex.yy.c
g++ -std=c++11 -c -g ast.cc
g++ -std=c++11 -c -g typecheck.cc
g++ -std=c++11 -c -g interp.cc
g++ -std=c++11 -g lex.yy.o ast.o typecheck.o interp.o syntax.tab.cc

# TODO: replace this with a script that can handle
# tests that are suppose to produce errors.
test:
./a.out examples/zero.6c
./a.out examples/next.6c
./a.out examples/while1.6c
./a.out examples/fun1.6c
./a.out examples/fun2.6c
./a.out examples/fun3.6c
./a.out examples/fun4.6c
./a.out examples/fun5.6c
./a.out examples/fun-recur.6c
./a.out examples/funptr1.6c
./a.out examples/block1.6c
./a.out examples/break1.6c
./a.out examples/continue1.6c
./a.out examples/struct1.6c
./a.out examples/struct2.6c
./a.out examples/choice1.6c
./a.out examples/tuple1.6c
./a.out examples/tuple2.6c
./a.out examples/tuple-match.6c
./a.out examples/tuple-assign.6c
./a.out examples/record1.6c
./a.out examples/match-int.6c
./a.out examples/match-int-default.6c
./a.out examples/match-type.6c
./a.out examples/pattern-init.6c
./a.out examples/struct3.6c

clean:
rm -f a.out
rm -f *.o
rm -f syntax.tab.h
rm -f syntax.tab.cc syntax.tab.c syntax.output
rm -f lex.yy.c lex.yy.cc
rm -f a.out
rm -rf a.out.dSYM
rm -f log
rm -f *~
rm -f examples/*~
133 changes: 133 additions & 0 deletions executable-semantics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Executable Semantics

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.l`](./syntax.l) the lexer specification
- [`syntax.y`](./syntax.y) the grammar

The parser translates program text into an abstract syntax tree (AST).

- [`ast.h`](./ast.h) includes structure definitions for the AST and function
declarations for creating and printing ASTs.
- [`ast.cc`](./ast.cc) contains the function definitions.

The type checker 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.

- [`typecheck.h`](./typecheck.h)
- [`typecheck.cc`](./typecheck.cc)

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.

- [`interp.h`](./interp.h) declares the `interp_program` function.
- [`interp.cc`](./interp.cc) implements `interp_program` function using an
abstract machine, 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 `Act` 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 `step_exp` 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 `handle_value` 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 `handle_value` 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 `copy_val` 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 [`examples/`](./examples/) subdirectory includes some example programs.
33 changes: 33 additions & 0 deletions executable-semantics/assoc_list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef ASSOC_LIST_H
#define ASSOC_LIST_H

#include <iostream>
#include <string>
using std::cerr;
using std::endl;

template<class K, class V>
struct AList {
K key;
V value;
AList* next;
AList(K k, V v, AList* n) : key(k), value(v), next(n) { }
};

template<class K, class V>
V lookup(int lineno, AList<K,V>* alist, K key, void (*print_key)(K)) {
if (alist == NULL) {
cerr << lineno << ": could not find `";
print_key(key);
cerr << "`" << endl;
exit(-1);
} else if (alist->key == key) {
return alist->value;
} else {
return lookup(lineno, alist->next, key, print_key);
}
}



#endif
Loading