interpre ng and
play

Interpre'ng and that can refer to integer arguments. Compiling - PowerPoint PPT Presentation

A New Mini-Language: Intex Intex programs are simple arithme'c expressions on integers Interpre'ng and that can refer to integer arguments. Compiling Intex Intex is the first in a sequence of mini-languages that can be extended to culminate in


  1. A New Mini-Language: Intex Intex programs are simple arithme'c expressions on integers Interpre'ng and that can refer to integer arguments. Compiling Intex Intex is the first in a sequence of mini-languages that can be extended to culminate in something that is similar to Racket. At each step along the way, we can add features that allow us to study different programming language dimensions. • Intex : integer expressions, posi'onal program arguments • Bindex : Intex + named arguments & local naming • Valex : Bindex + condi'onals, mul'ple kinds of values CS251 Programming Languages (booleans, strings, lists), dynamic type checking, Spring 2019, Lyn Turbak and syntac'c sugar • HOFL (Racket-like language): Valex + first-class func'ons Department of Computer Science • HOILEC : HOFL + SML-like explicit mutable cells Wellesley College • HOILIC : HOFL + Racket-like implicit mutable cells Intex 2 How do we write this Intex program as SML SOP tree? Intex Syntax Trees & Syntac'c Data Types As an s-expression? datatype pgm = Intex of int * exp Intex and exp = Int of int numargs body | Arg of int Intex | BinApp of binop * exp * exp 1 BinApp numargs body and binop = Add | Sub | Mul | Div | Rem rator rand1 rand2 2 BinApp (* Sample AST as SOP tree *) Div BinApp Int val avg = rator rand1 rand2 Intex(2, rator rand1 rand2 value Div BinApp Int BinApp(Div, BinApp(Add, Arg 1, Arg 2), Mul BinApp Int 9 rator rand1 rand2 value Int 2)) rator rand1 rand2 value Add Arg Arg 2 (* Sample AST as s-expression *) Sub Arg Int 5 (intex 2 (/ (+ ($ 1) ($ 2)) 2) index index index value ; can even write: 1 2 (intex 2 (/ (+ $1 $2) 2) 1 32 Intex 3 Intex 4

  2. Intex Interpreter Without Error Checking: Intex Implementa'on #1: Skeleton Intex Interpreter in SML (* val run: Intex.pgm -> int list -> int *) fun run (Intex(numargs, exp)) args = Given an avg-in-Intex program, how can we execute it? (* val eval: Intex.exp -> int list -> int *) avg machine (I) and eval (Int i) args = q avg-in-Intex program | eval (Arg index) args = q Intex interpreter machine (I) | eval (BinApp(binop, exp1, exp2)) args = ² Intex-interpreter-in-SML program ² SML interpreter machine in csenv/wx VM (ignore details) (* val binopToFun: Intex.binop -> int * int -> int *) and binopToFun Add = op+ | binopToFun Mul = op* | binopToFun Sub = op- | binopToFun Div = (fn(x,y) => x div y) | binopToFun Rem = (fn(x,y) => x mod y) Intex 5 Intex 6 Intex Interpreter With Error Checking Try it out exception EvalError of string - run (Intex(1, BinApp(Mul, Arg 1, Arg 1))) [5]; (* val run: Intex.pgm -> int list -> int *) val it = 25 : int fun run (Intex(numargs, exp)) args = if numargs <> length args then raise EvalError - run (Intex(1, BinApp(Div, Arg 1, Arg 1))) [5]; "Mismatch between expected and actual number of args" val it = 1 : int else eval exp args - run (Intex(1, BinApp(Div, Arg 1, Arg 1))) [0]; (* val eval: Intex.exp -> int list -> int *) and eval (Int i) args = i uncaught exception EvalError | eval (Arg index) args = if (index <= 0) orelse (index > length args) - run avg [5,15]; then raise EvalError "Arg index out of bounds" val it = 10 : int else List.nth(args, index-1) | eval (BinApp(binop, exp1, exp2)) args = let val i1 = eval exp1 args - map (run f2c) [[~40], [0], [32], [98], [212]]; val i2 = eval exp2 args val it = [~40,~18,0,36,100] : int list in ( case (binop, i2) of (Div, 0) => raise EvalError "Division by 0" | (Rem,0) => raise EvalError "Remainder by 0" | _ => (binopToFun binop)(i1, i2)) end Intex 7 Intex 8

  3. Handling Errors Intex programs as S-expression strings (* val testRun: Intex.pgm -> int list -> string *) Intex(1, BinApp(Mul, Arg 1, Arg 1) "(intex 1 (* ($ 1) ($ 1))" fun testRun pgm args = Int.toString (run pgm args) (* Convert to string so same type as error messages below *) Intex(2, BinApp(Div, handle EvalError msg => "EvalError: " ^ msg BinApp(Add, Arg 1, Arg 2), | other => "Unknown exception: " ^ (exnMessage other) Int 2)) "(intex 2 (/ (+ ($ 1) ($ 2)) 2))" - testRun (Intex(1, BinApp(Div, Arg 1, Arg 1))) [5]; val it = "1" : string Intex(1, - testRun (Intex(1, BinApp(Div, Arg 1, Arg 1))) [0]; BinApp(Div, BinApp(Mul, val it = "EvalError: Division by 0" : string BinApp(Sub, Arg 1, Int 32), Int 5), - map (testRun f2c) [[~40], [0], [32], [98], [212]]; Int 9)) val it = ["~40","~18","0","36","100"] : string list "(intex 1 (/ (* (- ($ 1) 32) 5) 9))" Intex 9 Intex 10 Running Intex programs as S-expression strings A Read-Eval-Print Loop (REPL) in Intex (* val testRun': string -> string -> string *) - repl(); fun testRun' pgmSexpString argsSexpString = intex> (+ 1 2) testRun (stringToPgm pgmSexpString) 3 (sexpStringToIntList argsSexpString) handle SexpError (msg, sexp) => intex> (#args 6 7) ("SexpError: " ^ msg ^ " " ^ (Sexp.sexpToString sexp)) intex> (+ ($ 1) ($ 2)) | Sexp.IllFormedSexp msg => 13 ("SexpError: Ill-formed sexp " ^ msg) | other => "Unknown exception: " ^ (exnMessage other) intex> ( * $1 $2) 42 - testRun' "(intex 2 (/ (+ ($ 1) ($ 2)) 2))" "(5 15)"; intex> (#run (intex 2 (/ (+ ($ 1) ($ 2)) 2)) 5 15) val it = "10" : string 10 - map (testRun' "(intex 1 (/ (* (- ($ 1) 32) 5) 9))") intex> (#run "avg.itx" 5 15) = ["(-40)", "(0)", "(32)", "(98)", "(212)"]; 10 val it = ["~40","~18","0","36","100"] : string list intex> (#run avg.itx 5 15) 10 - map (testRun' "(intex 1 (/ ($ 1) ($ 1)))")= = ["(-17)", "(0)", "(42)"]; intex> (#quit) Moriturus te saluto! val it = ["1”,"EvalError: Division by 0","1"] : string list Intex 11 Intex 12

  4. What do we know about this program? Dynamic vs. Sta'c Checking: Arg Indices Dynamic check (at runJme) : val test = Intex(2, BinApp(Sub, | eval (Arg index) args = BinApp(Mul, Arg 1, Arg 3), if (index <= 0) orelse (index > length args) Arg 2)) then raise EvalError "Arg index out of bounds" else List.nth(args, index-1) StaJc check (at compile Jme or checking Jme, before runJme) : Idea: We know numargs from program, so can use this to check all argument references without running the program. Such checks are done by examining thee program syntax tree. O\en there is a choice between a bo)om-up and top-down approach to processing the tree. You will do both approaches for Arg index checking in PS9. Intex 13 Intex 14 Sta'c Arg Index Checking: Top Down (PS9) Sta'c Arg Index Checking: Bo`om Up (PS9) 2. Check if in 1. Calculate (min,max) inclusive range 1. In top-down phase, index value for every (1, numargs) pass numargs to subexpression in tree every subexpression in bo`om-up fashion in program. 2 and (1,2) 2. Compare (min,max) 2. Check numargs against value at root of program every Arg index. body expression to (1, numargs), returning 2a. Return true for true if a subrange and Arg indices that pass 2 true and 2 false otherwise (1,2) (∞, -∞) test and subexps without arg indices 2b. Return false if any Arg index fails test. 2 true 2 true (1,1) (2,2) Intex 15 Intex 16

Recommend


More recommend