review: concrete syntax for impcore

Post on 12-Mar-2022

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Review: Concrete syntax for Impcore

Definitions and expressions:

def ::= (define f (x1 ... xn) exp)

| (val x exp)

| exp

| (use filename)

| (check-expect exp1 exp2)

| (check-error exp)

exp ::= integer-literal ;; atomic forms

| variable-name

| (set x exp) ;; compound forms

| (if exp1 exp2 exp3)

| (while exp1 exp2)

| (begin exp1 ... expn)

| (function-name exp1 ... expn)

How to define behaviors inductively

Expressions only

Base cases (plural): numerals, names

Inductive steps: compound forms

• To determine behavior of a compound form, look

at behaviors of its parts

First, simplify the task of definition

What’s different? What’s the same?

x = 3; (set x 3)

while (i * i < n) (while (< (* i i) n)

i = i + 1; (set i (+ i 1)))

Abstract away gratuitous differences

(See the bones beneath the flesh)

Abstract syntax

Same inductive structure as BNF

More uniform notation

Good representation in computer

Concrete syntax: sequence of symbols

Abstract syntax: ???

The abstraction is a tree

The abstract-syntax tree (AST):

Exp = LITERAL (Value)

| VAR (Name)

| SET (Name name, Exp exp)

| IFX (Exp cond, Exp true, Exp false)

| WHILEX (Exp cond, Exp exp)

| BEGIN (Explist)

| APPLY (Name name, Explist actuals)

One kind of “application” for both user-defined and primitive

functions.

In C, trees are a bit fiddly

typedef struct Exp *Exp;

typedef enum {

LITERAL, VAR, SET, IFX, WHILEX, BEGIN, APPLY

} Expalt; /* which alternative is it? */

struct Exp { // only two fields: ’alt’ and ’u’!

Expalt alt;

union {

Value literal;

Name var;

struct { Name name; Exp exp; } set;

struct { Exp cond; Exp true; Exp false; } ifx;

struct { Exp cond; Exp exp; } whilex;

Explist begin;

struct { Name name; Explist actuals; } apply;

} u;

};

Let’s picture some trees

An expression:

(f x (* y 3))

(Representation uses Explist)

A definition:

(define abs (n)

(if (< n 0) (- 0 n) n))

Behaviors of ASTs, part I: Atomic forms

Numeral: stands for a value

Name: stands for what?

In Impcore, a name stands for a value

Environment associates each variable with one value

Written � = fx1 7! n1; : : :xk 7! nkg,

associates variable xi with value ni.

Environment is finite map, aka partial function

x 2 dom� x is defined in environment �

�(x) the value of x in environment �

�fx 7! vg extends/modifies environment � to map x to v

Environments in C, abstractly

An abstract type:

typedef struct Valenv *Valenv;

Valenv mkValenv(Namelist vars, Valuelist vals);

bool isvalbound(Name name, Valenv env);

Value fetchval (Name name, Valenv env);

void bindval (Name name, Value val, Valenv env);

“Environment” is pointy-headed theory

You may also hear:

• Symbol table

• Name space

Influence of environment is “scope rules”

• In what part of code does environment govern?

Find behavior using environment

Recall

(* y 3) ;; what does it mean?

Your thoughts?

Impcore uses three environments

Global variables �

Functions �

Formal parameters �

There are no local variables

• Just like awk; if you need temps, use extra

formal parameters

• For homework, you’ll add local variables

Function environment � not shared with

variables—just like Perl

Syntax & environments determine behavior

Behavior is called evaluation

• Expression is evaluated in environment to

produce value

• “The environment” has three parts: globals,

formals, functions

Evaluation is

• Specified using inference rules (math)

• Implemented using interpreter (code)

You know code. You will learn math.

Key ideas apply to any language

Expressions

Values

Rules

Rules written using operational semantics

Evaluation on an abstract machine

• Concise, precise definition

• Guide to build interpreter

• Prove “evaluation deterministic” or

“environments can be on a stack”

Idea: “mathematical interpreter”

• formal rules for interpretation

Syntax & environments determine meaning

Initial state of abstract machine:

he; �;�;�i

State he; �;�;�i is

e Expression being evaluated

� Values of global variables

� Definitions of functions

� Values of formal parameters

Three

environments make a basis

Meaning expressed as “Evaluation judgment”

We say

he; �;�;�i + hv; �

;�;�

i

(Big-step judgment form.)

Notes:

• � and �

′ may differ

• � and �

′ may differ

• � must equal �Exercise: what do we know about globals, functions?

Impcore atomic form: literal

“Literal” generalizes “numeral”

LITERAL

hLITERAL(v); �;�;�i + hv; �;�;�i

Numeral converted to LITERAL(v) in parser

Impcore atomic form: variable name

Parameters hide global variables.

FORMALVAR

x 2 dom�

hVAR(x); �;�;�i + h�(x); �;�;�i

GLOBALVAR

x =2 dom� x 2 dom�

hVAR(x); �;�;�i + h�(x); �;�;�i

Impcore compound form: assignment

In SET(x;e), e is any expression

FORMALASSIGN

x 2 dom� he; �;�;�i + hv; �′

;�;�

i

hSET(x;e); �;�;�i + hv; �

;�;�

fx 7! vgi

GLOBALASSIGN

x =2 dom� x 2 dom� he; �;�;�i + hv; �

;�;�

i

hSET(x;e); �;�;�i + hv; �

fx 7! vg;�;�

i

Impcore can assign only to existing variables

Semantics corresponds to code

We compose rules to make proofs

Math Code

Semantics Interpreter

Evaluation judgment Result of evaluation

Proof of judgment Computation of result

Rule of semantics Case in the interpreter

Interpreter succeeds if and only if a proof exists

(Homework: result is unique!)

Code: Evaluate by cases

One case per rule; multiple cases per form:

VAR find binding for variable, use value

SET rebind variable in formals or globals

IFX (recursively) evaluate condition, then t or f

WHILEX (recursively) evaluate condition, body

BEGIN (recursively) evaluate each Exp of body

APPLY look up function in functions

built-in PRIMITIVE — do by cases

USERDEF function — use arg values to build

formals env, recursively evaluate fun body

Implementing evaluation

Value eval(Exp e, Valenv �, Funenv �, Valenv �) {

switch(e->alt) {

case LITERAL: return e->u.literal;

case VAR: ... /* look up in � and � */

case SET: ... /* modify � or � */

case IFX: ...

case WHILEX: ...

case BEGIN: ...

case APPLY: if (!isfunbound(e->u.apply.name, �))

runerror("undefined function %n",

e->u.apply.name);

f = fetchfun(e->u.apply.name, �);

... /* user fun or primitive */

}

}

Variable-form math: two rules

FORMALVAR

x 2 dom�

hVAR(x); �;�;�i + h�(x); �;�;�i

GLOBALVAR

x =2 dom� x 2 dom�

hVAR(x); �;�;�i + h�(x); �;�;�i

How do we tell them apart?

Variable-form code: three cases

Consult formals � or globals �:

case VAR:

if (isvalbound(e->u.var, formals))

return fetchval(e->u.var, formals);

else if (isvalbound(e->u.var, globals))

return fetchval(e->u.var, globals);

else

runerror("unbound variable %n", e->u.var);

Why a third case?

• When no proof, run-time error

Assignment-form math: two rules

FORMALASSIGN

x 2 dom� he; �;�;�i + hv; �

;�;�

i

hSET(x;e); �;�;�i + hv; �

;�;�

′fx 7! vgi

GLOBALASSIGN

x =2 dom� x 2 dom� he; �;�;�i + hv; �

;�;�

i

hSET(x;e); �;�;�i + hv; �

fx 7! vg;�;�

i

Assignment-form code: three cases

case VAR: {

Value v = eval(e->u.set.exp, globals, functions,

formals);

if (isvalbound(e->u.set.name, formals))

bindval(e->u.set.name, v, formals);

else if (isvalbound(e->u.set.name, globals))

bindval(e->u.set.name, v, globals);

else

runerror("set: unbound variable %n",

e->u.set.name);

return v;

}

Application math: user-defined function

APPLYUSER

�(f) = USER(hx1; : : : ;xni;e)x1; : : : ;xn all distinct

he1; �0;�;�0i + hv1; �1;�;�1i

he2; �1;�;�1i + hv2; �2;�;�2i

...

hen; �n−1;�;�n−1i + hvn; �n;�;�ni

he; �n;�;fx1 7! v1; : : : ;xn 7! vngi + hv; �

;�;�

i

hAPPLY(f ;e1; : : : ;en); �0;�;�0i + hv; �

;�;�ni

Simpler math: function of two parameters

APPLYUSER

�(f) = USER(hx1;x2i;e)

x1;x2 distinct

he1; �0;�;�0i + hv1; �1;�;�1i

he2; �1;�;�1i + hv2; �2;�;�2i

he; �n;�;fx1 7! v1;x2 7! v2gi + hv; �

;�;�

i

hAPPLY(f ;e1;e2; �0;�;�0i + hv; �

;�;�2i

Evaluating function application

The math demands these steps:

• Find function in old environment

f = fetchfun(e->u.apply.name, functions);

• Using old �, evaluate actuals

vs = evallist(e->u.apply.actuals,globals,functions,

formals);

N.B. actuals evaluated in current environment

• Make a new environment: bind formals to actuals

new_formals = mkValenv(f.u.userdef.formals, vs);

• Evaluate body in new environment

return eval(f.u.userdef.body, globals, functions,

new_formals);

top related