User Tools

Site Tools


cs330_f2016:labw

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
cs330_f2016:labw [2017/02/10 15:15]
wingated
cs330_f2016:labw [2021/06/30 23:42] (current)
Line 6: Line 6:
 ====Pre-requisite:​==== ====Pre-requisite:​====
  
-For this lab, you should have Julia 0.4+ installed, the same as for the rudimentary interpreter. ​ You will need both the Lexer and Error modules.+For this lab, you should have Julia 1.installed, the same as for the rudimentary interpreter. ​ You will need both the Lexer and Error modules.
  
 ---- ----
Line 15: Line 15:
 The primary deliverable for this lab is a new Julia module. ​ Your module should export ''​parse''​ and ''​calc''​ functions, and two return types, ''​NumVal''​ and ''​ClosureVal''​. The primary deliverable for this lab is a new Julia module. ​ Your module should export ''​parse''​ and ''​calc''​ functions, and two return types, ''​NumVal''​ and ''​ClosureVal''​.
  
-Your module should be able to do everything that your simple interpreter could do (all unary, binary operations, and built-in functions). ​ In addition, your new interpreter must implement all of the functionality of the ''​CI5.jl''​ module, including ''​if0'' ​statements, closures and ''​lambda''​ statements, and ''​with''​ statements.+Your module should be able to do everything that your simple interpreter could do (all unary, binary operations, and built-in functions). ​ In addition, your new interpreter must implement all of the functionality of the ''​CI3.jl''​ module ​from class, including ''​if0'' ​expressions, closures and ''​lambda''​ statements, and ''​with''​ statements.
  
 However, you will need to extend the functionality of several of these statements, as described below. However, you will need to extend the functionality of several of these statements, as described below.
Line 21: Line 21:
 You must also do some basic error handling. You must also do some basic error handling.
  
-The ''​CI5.jl''​ module is available ​on LearningSuite,​ under "Content ​-> Julia -> Functions and Closures"​.+The ''​CI3.jl''​ module is available ​in the Content ​section on the class'​s Learning Suite pages.
  
 Please name your module ExtInt. Please name your module ExtInt.
Line 31: Line 31:
  
 <code BNF> <code BNF>
-<OWL> ::= number +<AE> ::= number 
-          | (+ <OWL> <OWL>) +          | (+ <AE> <AE>) 
-          | (- <OWL> <OWL>) +          | (- <AE> <AE>) 
-          | (* <OWL> <OWL>) +          | (* <AE> <AE>) 
-          | (/ <OWL> <OWL>) +          | (/ <AE> <AE>) 
-          | (mod <OWL> <OWL>) +          | (mod <AE> <AE>) 
-          | (collatz <OWL>) +          | (collatz <AE>) 
-          | (- <OWL>)      ​+          | (- <AE>)      ​
           | id           | id
-          | (if0 <OWL> <OWL> <OWL>)+          | (if0 <AE> <AE> <AE>)
           ​           ​
           # Major change: function definitions,​ calls &           # Major change: function definitions,​ calls &
Line 46: Line 46:
           # Note the extra parens.           # Note the extra parens.
           ​           ​
-          | (with ( (id <OWL>)* ) <OWL>) +          | (with ( (id <AE>)* ) <AE>) 
-          | (lambda (id*) <OWL>) +          | (lambda (id*) <AE>) 
-          | (<OWL> <OWL>​*) ​        +          | (<AE> <AE>​*) ​        
 </​code>​ </​code>​
  
-where ''​number''​ is a Julia Real and ''​id''​ is not '+, '-, '*, '/, 'with, 'if0, 'mod, '​collatz,​ or '​lambda.+where ''​number''​ is a Julia Real and ''​id'' ​is a Julia Symbol that is not '':+''​, '':-''​, '':*''​, '':/''​, '':with''​, '':if0''​, '':mod''​, '':collatz''​, or '':lambda''​. 
 Here the "​*"​ notation is the Kleene star (zero or more occurrences) you should have seen in CS 236 and/or CS 252. Here the "​*"​ notation is the Kleene star (zero or more occurrences) you should have seen in CS 236 and/or CS 252.
  
-Remember, this grammar is for the quoted S-expressions; ​the lexer will return data structures that put everything between parentheses into an array (removing the parentheses). ​+Remember, this grammar is for the concrete syntax: ​the lexer will return data structures that put everything between parentheses into an array (removing the parentheses). ​
  
 This grammar blends both the grammar for the simple interpreter and the in-class interpreter we have built, but also expands several of the functions. This grammar blends both the grammar for the simple interpreter and the in-class interpreter we have built, but also expands several of the functions.
Line 81: Line 82:
 (lambda x (+ x 1)) (lambda x (+ x 1))
 or or
-(with x 5 (+ x 1))+(with (x 5(+ x 1))
 </​code>​ </​code>​
  
Line 96: Line 97:
 ===Error handling:​=== ===Error handling:​===
  
-This interpreter needs to be able to handle new kinds of errors. ​ We expect you to properly catch both **type errors** ​and **syntax errors**. Remember the parser'​s job is to reject input that does not fit the grammar and output an abstract syntax tree when it does. The Interpreters job is too interpret an abstract syntax tree and throw an error on invalid computations.+This interpreter needs to be able to handle new kinds of errors. ​ We expect you to properly catch both **type errors** ​**syntax ​errors** and **arity ​errors**. Remember the parser'​s job is to reject input that does not fit the grammar and output an abstract syntax tree when it does. The Interpreters job is to interpret an abstract syntax tree and throw an error on invalid computations.
  
 **For type errors:** There are a couple of times when types are essential. ​ For example, when we evaluate a ''​Plus''​ node, we calculate the LHS and RHS, and then attempt to add them.  Obviously, we need to make sure that both the LHS and RHS returned numbers! ​ Similarly, when we calc a FunApp node, we evaluate a function expression -- it must result in a ''​ClosureVal''​. **For type errors:** There are a couple of times when types are essential. ​ For example, when we evaluate a ''​Plus''​ node, we calculate the LHS and RHS, and then attempt to add them.  Obviously, we need to make sure that both the LHS and RHS returned numbers! ​ Similarly, when we calc a FunApp node, we evaluate a function expression -- it must result in a ''​ClosureVal''​.
Line 106: Line 107:
 (lambda (x x) 10) (lambda (x x) 10)
 </​code>​ </​code>​
 +
 +**For arity errors:** Arity errors occur when a defined function is given too many or too few parameters. These should be caught when a function is applied, during the calc phase.
  
 **Remember to throw errors, not simply print error messages.** **Remember to throw errors, not simply print error messages.**
  
-Your parser and interpreter must detect errors and explicitly signal them by calling throw(LispError(Reason). We will consider an error raised internally by julia to be a bug in your code.+Your parser and interpreter must detect errors and explicitly signal them by calling throw(LispError(Reason). ​**We will consider an error raised internally by julia to be a bug in your code.**. Think how you'd feel as a programmer if an error in your source code caused your compiler to crash instead of telling you what was wrong.
  
 To include LispError put "using Error" after the module declaration of you code. Error is a module containing LispError. To include LispError put "using Error" after the module declaration of you code. Error is a module containing LispError.
- 
-For example, Julia signals a “divide by zero” error if you attempt to evaluate (/ 1 0). Since we use Julia'​s division function to implement division in OWL, you may be tempted to leave it to Julia to signal division by zero errors for you. However, you must signal the error yourself by explicitly testing for division by zero before calling Julia'​s division procedure. 
  
 ---- ----
Line 126: Line 127:
 # Abstract syntax # Abstract syntax
  
-abstract ​OWL+abstract ​type AE end
  
-type NumNode <: OWL+struct ​NumNode <: AE
     n::Real     n::Real
 end end
  
-type Binop <: OWL +struct BinopNode ​<: AE 
-    op::Symbol +    op::Function 
-    lhs::OWL +    lhs::AE 
-    rhs::OWL+    rhs::AE
 end end
  
-type If0 <: OWL +struct If0Node ​<: AE 
-  condition::OWL +  condition::AE 
-  zero_branch::​OWL +  zero_branch::​AE 
-  nonzero_branch::​OWL+  nonzero_branch::​AE
 end end
  
-type With <: OWL +struct WithNode ​<: AE 
-  ​name::Symbol +  ​sym::Symbol 
-  binding_expr::​OWL +  binding_expr::​AE 
-  body::OWL+  body::AE
 end end
  
-type Id <: OWL +struct VarRefNode ​<: AE 
-  ​name::Symbol+  ​sym::Symbol
 end end
  
-type FunDef ​<: OWL +struct FunDefNode ​<: AE 
-    ​formal_parameter::Symbol +  ​formal::Symbol 
-    fun_body::OWL+  fun_body::AE
 end end
  
-type FunApp ​<: OWL +struct FunAppNode ​<: AE 
-    fun_expr::OWL +  fun_expr::AE 
-    arg_expr::OWL+  arg_expr::AE
 end end
  
-# Rejigger our type hierarchy to better support return values+abstract ​type RetVal end
  
-abstract ​RetVal+abstract ​type Environment end
  
-type NumVal <: RetVal+struct ​NumVal <: RetVal
   n::Real   n::Real
 end end
  
-type ClosureVal <: RetVal +struct ​ClosureVal <: RetVal 
-    param::Symbol +  ​formal::Symbol 
-    body::OWL +  body::AE 
-    env::​Environment ​ # this is the environment at definition time!+  env::​Environment
 end end
  
-# Definitions for our environment data structures +struct EmptyEnv ​<: Environment
- +
-abstract Environment +
- +
-type mtEnv <: Environment+
 end end
  
-type CEnvironment ​<: Environment +struct ExtendedEnv ​<: Environment 
-  ​name::Symbol +  ​sym::Symbol 
-  ​value::RetVal+  ​val::RetVal
   parent::​Environment   parent::​Environment
 end end
Line 202: Line 199:
  
 <code Julia> <code Julia>
-function parse(expr::​Array{Symbol or Real}+function parse(expr::​Any
-function calc(ast::OWL)+function calc(ast::AE)
 </​code>​ </​code>​
  
Line 210: Line 207:
 **Conditionals:​** **Conditionals:​**
  
-The semantics of (if0 test then else) is: if the test evaluates to zero, then the entire expression evaluates to the result of then, otherwise, it evaluates to else. Evaluation should signal an error for non-numeric test values.+The semantics of (if0 test then else) is as follows: if the test evaluates to zero, then the entire expression evaluates to the result of then expression, otherwise, it evaluates to the result of the else expression. Evaluation should signal an error for non-numeric test values.
  
 **Multi-argument fun** **Multi-argument fun**
cs330_f2016/labw.1486739747.txt.gz · Last modified: 2021/06/30 23:40 (external edit)