220 likes | 341 Views
第4章 : 式・値・環境. 式 : 言語の基本的な構文要素のひとつ 式は値を表わすもの 同時にこの値を計算する手順を表現する 一般的な式の構成と計算の手順の表現を扱う. 復習:加減演算式. data Expr = Num Numeral | Pexpr Expr Expr | Mexpr Expr Expr. 29+31: Pexpr (Num “ 29 ” ) (Num “ 31 ” ). 加減演算式:演算の一般化. data Expr = Num Numeral
E N D
第4章: 式・値・環境 式: 言語の基本的な構文要素のひとつ 式は値を表わすもの 同時にこの値を計算する手順を表現する 一般的な式の構成と計算の手順の表現を扱う
復習:加減演算式 • data Expr = Num Numeral • | Pexpr Expr Expr • | Mexpr Expr Expr 29+31: Pexpr (Num “29”) (Num “31”)
加減演算式:演算の一般化 • data Expr = Num Numeral • | Pexpr Expr Expr • | Mexpr Expr Expr • data Expr = Num Numeral • | Bexpr BinOpr Expr Expr • data BinOpr = Plus | Minus 29+31: Bexpr Plus (Num “29”) (Num “31”)
四則演算式への拡張 • data Expr = Num Numeral • | Bexpr BinOpr Expr Expr • data BinOpr = Plus | Minus • data Expr = Num Numeral • | Bexpr BinOpr Expr Expr • data BinOpr = Plus | Minus | Times | Over 29+31*2: Bexpr Plus (Num “29”) (Bexpr Times (Num “31”) (Num “2”))
変数と宣言の導入 (29+31)*3-(29+31)*(29+31) letx=29+31 inx*3-x*x Declaration Variable
変数と宣言の構文 • data Expr = Num Numeral • | Bexpr BinOpr Expr Expr data Expr = Num Numeral | Bexpr BinOpr Expr Expr | Var Ide | Let Decl Expr data Decl = Decl Ide Expr
変数と宣言の構文:例 data Expr = Num Numeral | Bexpr BinOpr Expr Expr | Var Ide | Let Decl Expr data Decl = Decl Ide Expr letx=29+31inx*3-x*x Let (Decl "x" (Bexpr Plus (Num "29") (Num "31"))) (Bexpr Minus (Bexpr Times (Var "x") (Num "3")) (Bexpr Times (Var "x") (Var "x")) )
変数と宣言の意味1 expval :: Expr -> Env -> Val type Val = Int 環境 Env type Env = Assoc Ide Val - none - lookup_ r x - update r x v
変数と宣言の意味2 • 変数の値: 環境rのもとで変数xの表わす値は • expval (Var x) r = lookup r x • 変数の宣言: 環境を更新するのが宣言の効果 • 宣言の意味を与える関数 • declenv :: Decl -> Env -> Env -> Env • declenv (Decl x e) r' r = update r x (expval e r')
式の意味 expval (Num n) r = numval n expval (Var x) r = lookup_ r x expval (Bexpr o e e') r = binopr o (expval e r) (expval e' r) expval (Let d e) r = expval e (declenv d r r) binopr Plus = (+) binopr Minus = (-) binopr Times = (*) binopr Over = div eval e = expval e none
宣言の入れ子構造 expval (Let d (Let d' e)) r = expval (Let d' e) (declenv d r r) = expval e (declenv d' r' r') • 有効範囲(scope): 宣言の効果の及ぶ範囲のこと • Let (Decl "x" e1) (Bexpr Plus e2 (Let (Decl "x" e3) e4) )
実験 1 講義のホームページからソースを入手 Parselib.hs Scanlib.hs Synlib.hs Semlib.hs Syn_4_2.hs Sem_4_2.hs 2 ソースのdirectory: hugsを起動 3 :load Sem_4_2.hs 4 構文解析関数parseと意味関数eval:実験 重要!
再帰的な宣言 data Expr = Num Numeral | Bexpr BinOpr Expr Expr | Var Ide | Let Decl Expr data Expr = Num Numeral | Bexpr BinOpr Expr Expr | Var Ide | Let [Decl] Expr letx=y; y=3in x+y
再帰的な宣言の意味 expval (Let ds e) r = expval e (recdecl ds r) recdecl :: [Decl] -> Env -> Env recdecl ds r = r” where r” = foldl declenv' r ds declenv' r' d = declenv d r” r' letx=y; y=3in x+y 6
条件式 • 条件式(conditional expression):条件に応じて異なる値を表わす式 ifn=0then 1 else n*2 式の表現力が向上 関係式
条件式の構文 data Expr = … | Rexpr RelOpr Expr Expr | If Expr (Expr,Expr) data RelOpr = Equal | NotEqual | Greater | GreaterEq | Less | LessEq if n=0 then 1 else n*2 : If (Rexpr Equal (Var "n") (Num "0")) (Num "1", Bexpr Times (Var "n") (Num "2"))
関係式の意味 • 型 Val を拡張 data Val = V_Int Int | V_Bool Bool • 評価関数 expval (Rexpr o e e') r = V_Bool (relopr o v v') where V_Int v = expval e r V_Int v' = expval e' r relopr :: RelOpr -> Int -> Int -> Bool relopr Equal = (==) relopr NotEqual = (/=) …
条件式の意味 expval (If e (e',e'')) r | v = expval e' r | otherwise = expval e'' r where V_Bool v = expval e r
今までの評価関数 expval :: Expr -> Env -> Val expval (Num n) r = V_Int (numval n) expval (Var x) r = lookup r x expval (Let ds e) r = expval e (recdecl ds r) expval (Bexpr o e e') r = V_Int (binopr o v v') where V_Int v = expval e r V_Int v' = expval e' r expval (Rexpr o e e') r = V_Bool (relopr o v v') where V_Int v = expval e r V_Int v' = expval e' r expval (If e (e',e'')) r | v = expval e' r | otherwise = expval e'' r where V_Bool v = expval e r
関数抽象式・関数適用式 data Expr = … | Fun Ide Expr | Apply Expr Expr \x-> x * x: Fun "x" (Bexpr Times (Var "x") (Var "x")) square 5: Apply (Var "square") (Num "5")
関数抽象・適用式の意味 data Val = V_Int Int | V_Bool Bool | V_Fun (Val -> Val) expval :: Expr -> Env -> Val expval (Fun x e) r = V_Fun f where f v = expval e (update r x v) expval (Apply e e') r = f (expval e' r) where V_Fun f = expval e r
実験 • :load Sem_4_5.hs • eval “let f n = if n=0 then 1 else n*f(n-1) in f 5” 120