Listoflectures TDDA69DataandProgramStructure Evaluation CyrilleBerger 1IntroductionandFunctionalProgramming 2ImperativeProgrammingandDataStructures 3Parsing 4Evaluation 5ObjectOrientedProgrammingandtypessystem 6Macrosanddecorators 7VirtualMachinesandBytecode 8GarbageCollectionandNativeCode 9ConcurrentComputing 10DeclarativeProgramming 11LogicProgramming 12Summary 2/62 Howisaprograminterpreted? Lecturecontent Sourcecode SubstitutionModel EnvironmentModel Parser Parser Environment Evaluationrules EvaluationandEnvironment AssignmentandEnvironment FunctionsandEnvironment Scope TheScopeTrap Writinganevaluator 3/62 AbstractSyntaxTree Treevisitor Generator Sourcecode Bytecode VirtualMachine Assembler Assembly ... OperatingSystem CPU 4/62 SubstitutionModel-Example(1/2) (define(squarex)(*xx)) (define(sum-of-squaresxy) (+(squarex)(squarey))) (define(fa) (sum-of-squares(+a1)(*a2))) Howtoevaluate(f(+14))? SubstitutionModel 6 SubstitutionModel-Example(2/2) SubstitutionModel Toevaluate: Toevaluateacombinationwitha compoundprocedureasoperator: (f(+14) Evaluatethearguments (f5) Fetchthevalueoff evaluatetheelementsofthecombination applytheprocedure(i.e.valueftheoperator) tothearguments(i.e.valuesoftheoperands): evaluatethebodyoftheprocedurewhere eachformalparameterisreplacedbythe correspondingargument (sum-of-squares(+a1)(*a2))) Replaceaby5 (sum-of-squares(+51)(*52)) Evaluatethearguments (sum-of-squares610) Fetchthevalueofsum-of-squaresandreplacethearguments: (+(square6)(square10)) Andsoon: (+(*66)(*1010)) (+36100) 136 Thisisthesubstitutionmodelintheapplicativeorder 7 8 ApplicativevsNormal-Example(1/2) ApplicativevsNormal (define(squarex)(*xx)) Recursivelyevaluateallthe subexpressions,butinwhatorder? Applicative order Applicativeorder:evaluatetheargumentsand thenapply.Evaluatetheprocedurebodywith everyformalparameterreplacedwiththe correspondingargumentvalue Normalorder:fullyexpandandthenreduce. Recursivelyexpandeveryprocedureuntilonly primitiveoperatorsareleft.Evaluate(reduce) theresult. (square(*42)) (square(*8)) (*88) 64 Normalorder (square(*42)) (*(*42)(*42)) (*88) 64 Forprocedureapplicationsthatcanbemodeledwiththe substitutionmodelthatterminatewithlegitimatevalues, applicativeandnormalorderproducethesamevalue. 9 ApplicativevsNormal-Example(2/2) Normalorderandlazyevaluation if(objectandobject.count() andobject.sum()/ object.count()>0.90): print('Highsuccessrate!') (define(fooxy (if(=x0)y(*2x)))) Applicative order (foo10(/200)) error:divisionby zero 10 Normalorder (foo10(/200)) (if(=100)(/200) (*210)) (*210) 20 Whatistheresult?www.govote.at253312 start 11 12 Assignmentandthesubstitutionmodel(1/2) (define(make-withdrawbalance) (lambda(amount) (set!balance(-balanceamount)) balance)) (defineW(make-withdraw25)) (W20) 5 (W10) -5 Assignmentandthesubstitutionmodel(2/2) (define(make-withdrawbalance) (lambda(amount) (set!balance(-balanceamount)) balance)) (defineW(make-withdraw25)) (W20) ((make-withdraw25)20) ((lambda(amount)(set!balance(-balanceamount)) 25)20) ((set!balance(-2520))25) 25 13 14 Whydoesn’tthesubstitutionmodelwork? Substitutionisbasedonthenotion thatsymbolsarenamesforvalues Usingset!changessymbolstoplaces wherevaluescanbestored Thevalueinsuchaplacecanchange usingassignmentwithset! Anewmodelofevaluationisneeded: theenvironmentmodelofevaluation. 15 EnvironmentModel Assignment Bindsnamestovalues a := 2 Nowahasthevalue2 Environment a plus 2 evaluatesto4 Thisimplythataisstored somewhere! 18 Environment FromtheSICPBook,section3.2: Bindingsassociatevariablestovalues(in assignmentexpression) Aframeisasetofbindings Anenvironmentisasequenceofframes Environmentsdescribecontextswhere expressionsareevaluated Everyframepointstothefollowingframein theenvironment Allenvironmentshaveaglobalframeas thelastframeinthesequence Theglobalenvironmentisaframewithall predefinedbindings Scopetherangeinwhichavariablecanbe referenced nil:... pi:3.14... ... EnvironmentDiagram (global)I nil:... pi:3.14... ... II a:6 f:[34] ... VI a:2 m:4 ... 19 f:6 m:{'key':1} ... (global)I a:6 f:[34] ... II m:1 y:2 ... III IV a:1 ... V a:2 m:4 ... VI 20 EnvironmentsDiagrams Environment diagramsvisualize theinterpreter's process nil:... pi:3.14... ... (global)I II a:6 f:[34] ... a:2 m:4 ... Evaluationrules VI 21 Evaluationrules-Example Evaluationrules Afunctionisevaluated,bycreatinganew frameandbindingtheargumentsintheframe Afunctionisstoredasalambdarepresenting thefunctionbodyandapointertothe environmentwherethefunctioniscreated http://tinyurl.com/z9mabuh 23 24 NameshavenoMeaningwithoutEnvironments Variables(andhenceexpressions) donothavemeaningsin themselves Variablesforwhichthereisno bindinginanenvironmentaresaid tobeunbound Avariablecanhaveatmostone bindingperframe EvaluationandEnvironment 26 Evaluationofanexpression Namelook-up(1/2) NameshavenoMeaningwithout Environments... ...soexpressionsneedtobe associatedtoanenvironment Buthowdowegetthevalueof 'a'? Ifseveralbindingsexistforthe samevariableinanenvironment a plus thenthevariableisassociatedtotheclosest binding thatbindingissaidtoshadowtheother bindingsofthevariable 2 27 28 Namelook-up(2/2) Whatisthevalueofa? Whatisthevalueoff? Govoteat(forframeII) www.govote.at737756 Govoteat(forframeVI) www.govote.at228098 nil:... a:3... ... (global)I start f:6 m:{'key':1} ... a:6 f:2 ... II m:1 y:2 ... III IV a:1 ... V a:2 m:4 ... VI AssignmentandEnvironment 29 AssignmentStatement(1/2) Startinaclean state a=1 b=2 b,a=a+b,b Question (global)I Whatisthevalueofthefinal expressioninthissequence? a=2 b=3 >>>f=min >>>g=max >>>g,h=min,max >>>max=g >>>max(f(2,g(h(1,5),3)),4) www.govote.atentercode821391 31 32 AssignmentStatement(2/2) f=min g=max g,h=min,max max=g max(f(2,g(h(1,5),3)),4) ->2 Inwhichframetobind? (global)I WeareinFrameII: a=2 b=1 Whereshouldthe bindingofaandb bedone? min=funcmin(...) max=funcmax(...) (global)I a:0 c:34 II b:3 33 34 CallingUser-DefinedFunctions(1/2) Procedureforcallinguser-defined functions: FunctionsandEnvironment Addalocalframe Bindthefunction'sformalparameterstoits argumentsinthatframe Executethebodyofthefunctioninthatnew frame 36 NamesHaveDifferentMeaningsinDifferentEnvironments CallingUser-DefinedFunctions(2/2) (global)I fromoperatorimportmul defsquare(x): returnmul(x,x) square(-2) fromoperatorimportmul defsquare(square): ⠀⠀returnmul(square,square) square(-2) (square)II (global)I mul:funcmul(...) square:funcsquare(...) (square)II square:-2 x:-2 37 38 RecursioninEnvironmentDiagram Recursion deffact(n): n:3 ifn==0: return1 else: returnn*fact(n-1) fact(3) ⠀↳fact(2) ⠀⠀↳fact(1) ⠀⠀⠀↳fact(0) Thesamefunctioniscalled multipletime Differentframeskeeptrackofthe differentargumentsineachcall. Whatnevaluatestodepends uponwhichisthecurrentcontext. n:1 39 (fact)II (fact)III n:2 (global)I mul:funcmul(...) square:funcsquare(...) (fact)IV (fact)V n:0 40 LocalvsGlobal(1/4) deff(): print(s) s='World' f() Scope (global)I f:funcf(...) s:'World' (f)II 42 LocalvsGlobal(2/4) deff(): s='Hello' print(s) s='World' f() LocalvsGlobal(3/4) (global)I f:funcf(...) s:'World' (f)II s:'Hello' 43 deff(): print(s) s='Hello' print(s) s='World' f() UnboundLocalError:local variable's'referenced beforeassignment (global)I f:funcf(...) s:'World' (f)II s:undefined 44 LocalvsGlobal(4/4) deff(): globals print(s) s='Hello' print(s) s='World' f() InJavaScript (global)I f:funcf(...) s:'Hello' (f)II functionf() { vars='Hello' console.log(s) } s='World' f() console.log(s) functionf() { console.log(s) s='Hello' console.log(s) } s='World' f() 45 46 Functions-scopevsBlock-scope Python,JavaScript,Lisp...have function-scope C,C++,Java...haveblock-scope ForinstanceinC++: TheScopeTrap inta=1; { inta=2 } std::cout<<a<<std::endl; 47 TheScopetrap OutoftheScopeTrap functioncreate_arr() { vararr=[] for(vari=0;i<4;++i) { arr[i]=function(){console.log(i)} } returnarr; } functioncreate_arr() { vararr=[] for(vari=0;i<4;++i) { arr[i]=(function(value){returnfunction(){console.log(value)}})(i) } returnarr; } arr=create_arr() arr=create_arr() for(vari=0;i<4;++i) { arr[i]() } for(vari=0;i<4;++i) { arr[i]() } Whatisprinted?www.govote.at910291 http://tinyurl.com/h7b7r4c Howtosolve?www.govote.at327070 http://tinyurl.com/z7rqfrt 49 50 TheScopeTrapinC++ #include<vector> #include<functional> #include<iostream> ([i](){...})I i:1 std::vector<std::function<void()>>create_arr() { std::vector<std::function<void()>>val; for(inti=0;i<4;++i) { val.push_back([i](){std::cout<<i<<std::endl;}); } returnval; } intmain(intargc,char**argv) { std::vector<std::function<void()>>arr=create_arr(); for(std::function<void()>v:arr) { v(); } } Writinganevaluator (global)I (for(...))II i:1 InC++,capturedvariablesarecopiedinthelambdaframe 51 Usingthevisitorpatternforevaluation Howdoes interpeterwork inpractice? Wecanusethe visitorpattern. + ['+'[1 ['*'[4 ['/'[5 ['+'[23] ]]]]]]] * 1 defevaluate(node): ifnotisinstance(node,list): returnnode elifnode[0]=='+': returnevaluate(node[1][0]) +evaluate(node[1][1]) elifnode[0]=='-': returnevaluate(node[1][0]) -evaluate(node[1][1]) elifnode[0]=='*': returnevaluate(node[1][0]) *evaluate(node[1][1]) elifnode[0]=='/': returnevaluate(node[1][0]) /evaluate(node[1][1]) else: raiseError() / 4 Visitorinterpreter 5 + 2 3 + * 1 / 4 5 + 2 3 http://tinyurl.com/z8o234q 53 Definingvalue 54 Setvalue ['define'['x'10]] defevaluate(node): ... elifnode[0]=='define': currentFrame.define( node[1][0], evaluate(node[1][1])) ['set'['x'10]] defevaluate(node): ... elifnode[0]=='set': currentFrame.set( node[1][0], evaluate(node[1][1])) 55 56 Getvalue Condstatement [+['x'10]] defevaluate(node): ifnotisinstance(node,list): returnnode elifnode[0]=='+': ... defevaluate(node): ifnotisinstance(node,list): if(currentFrame.has(node)): returncurrentFrame.get(node) returnnode elifnode[0]=='+': ... ['cond'[[[<'x'0]['-'x]]], [[='x'0]0], ['T''x']]]] defevaluate(node): ... elifnode[0]=='cond': foreltinnode[1]: ifelt[0]=='T' orevaluate(elt[0]): returnevaluate(elt[2]) 57 Whilestatement 58 DefiningaLambda ['while'[<'x'10] ['set'['x'['+'['x'1]]] defevaluate(node): ... elifnode[0]=='while': whileevaluate(node[1][0]): evaluate(node[1][1]) ['lambda'[['x']['+''x'1]]] defevaluate(node): ... elifnode[0]=='lambda': return(array[1][0], array[1][1], currentFrame) 59 60 CallingaLambda Summary ['increment''x'] defevaluate(node): ... else: (args,body,frame)=currentFrame.get(node[0]) previousFrame=currentFrame currentFrame=createFrame(frame) foriinrange(0,len(args)): name=args[i] value=evaluate(node[1][i]) currentFrame.define(name,value) ret=evaluate(body) currentFrame=previousFrame returnret ParserandAbstractSyntaxTree EvaluationModels Howtobuildasimpleinterpreter 61 62/62