From 1e72ae4cb847268481a89a43b86df0f662dd76e0 Mon Sep 17 00:00:00 2001 From: <> Date: Mon, 19 Aug 2024 01:44:20 +0000 Subject: [PATCH] Deployed 759a95d with MkDocs version: 1.6.0 --- .nojekyll | 0 404.html | 1 + Data_Structures/index.html | 1 + abi/index.html | 27 + about/authors/index.html | 1 + about/license/index.html | 1 + about/philosophy/index.html | 1 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.fe8b6f2b.min.js | 29 + assets/javascripts/bundle.fe8b6f2b.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/stylesheets/main.3cba04c6.min.css | 1 + assets/stylesheets/main.3cba04c6.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + attribute/index.html | 122 + codegen/index.html | 44 + data-structures/index.html | 4 + .../abstract-syntax-tree/index.html | 52 + .../global-symbol-table/index.html | 32 + data_structures/local-symbol-table/index.html | 7 + data_structures/type-table/index.html | 25 + docker-setup/index.html | 30 + documentation/index.html | 1 + ex1/index.html | 40 + expl/index.html | 58 + explusagespec/index.html | 3 + extra.css | 87 + feedback/index.html | 1 + feedback/nitc-winter-2017/index.html | 1 + feedback/nitc-winter-2021/index.html | 1 + files/xsm_expl.tar.gz | Bin 0 -> 118262 bytes gdb-files/index.html | 112 + gdb/index.html | 136 + grammar-outline/index.html | 102 + help/index.html | 1 + img/2021_charts/1.png | Bin 0 -> 17509 bytes img/2021_charts/2-1.png | Bin 0 -> 13847 bytes img/2021_charts/3-1.png | Bin 0 -> 15486 bytes img/2021_charts/4-1.png | Bin 0 -> 18159 bytes img/2021_charts/5-1.png | Bin 0 -> 21734 bytes img/2021_charts/6-1.png | Bin 0 -> 18012 bytes img/2021_charts/7-1.png | Bin 0 -> 17018 bytes img/GitHub-Logo.png | Bin 0 -> 5970 bytes img/after call.png | Bin 0 -> 4838 bytes img/architecturemodel.png | Bin 0 -> 23981 bytes img/ast3.png | Bin 0 -> 11223 bytes img/ast31.png | Bin 0 -> 13013 bytes img/ast_stage2.png | Bin 0 -> 37739 bytes img/ast_stage4.png | Bin 0 -> 30569 bytes img/before call.png | Bin 0 -> 3571 bytes img/class_table_1.png | Bin 0 -> 11031 bytes img/class_table_2.png | Bin 0 -> 27356 bytes img/codegen.png | Bin 0 -> 305582 bytes img/compiler.gif | Bin 0 -> 72989 bytes img/creativecommons.png | Bin 0 -> 1635 bytes img/data_structure_1.png | Bin 0 -> 11129 bytes img/data_structure_10.png | Bin 0 -> 7250 bytes img/data_structure_11.png | Bin 0 -> 8031 bytes img/data_structure_12.png | Bin 0 -> 8291 bytes img/data_structure_13.png | Bin 0 -> 7806 bytes img/data_structure_14.png | Bin 0 -> 7927 bytes img/data_structure_15.png | Bin 0 -> 7991 bytes img/data_structure_16.png | Bin 0 -> 7927 bytes img/data_structure_17.png | Bin 0 -> 10317 bytes img/data_structure_18.png | Bin 0 -> 14993 bytes img/data_structure_19.png | Bin 0 -> 15493 bytes img/data_structure_2.png | Bin 0 -> 23882 bytes img/data_structure_20.png | Bin 0 -> 15511 bytes img/data_structure_21.png | Bin 0 -> 16176 bytes img/data_structure_22.png | Bin 0 -> 19314 bytes img/data_structure_23.png | Bin 0 -> 16549 bytes img/data_structure_24.png | Bin 0 -> 16419 bytes img/data_structure_25.png | Bin 0 -> 15909 bytes img/data_structure_26.png | Bin 0 -> 15564 bytes img/data_structure_27.png | Bin 0 -> 52539 bytes img/data_structure_28.png | Bin 0 -> 15268 bytes img/data_structure_29.png | Bin 0 -> 351001 bytes img/data_structure_3.png | Bin 0 -> 34763 bytes img/data_structure_31.png | Bin 0 -> 86667 bytes img/data_structure_32.png | Bin 0 -> 82039 bytes img/data_structure_33.png | Bin 0 -> 7570 bytes img/data_structure_34.png | Bin 0 -> 14336 bytes img/data_structure_35.png | Bin 0 -> 20201 bytes img/data_structure_36.png | Bin 0 -> 32055 bytes img/data_structure_37.png | Bin 0 -> 17535 bytes img/data_structure_38.png | Bin 0 -> 7473 bytes img/data_structure_39.png | Bin 0 -> 4396 bytes img/data_structure_4.png | Bin 0 -> 5886 bytes img/data_structure_40.png | Bin 0 -> 15798 bytes img/data_structure_41.png | Bin 0 -> 18255 bytes img/data_structure_42.png | Bin 0 -> 28874 bytes img/data_structure_43.png | Bin 0 -> 39006 bytes img/data_structure_44.png | Bin 0 -> 35110 bytes img/data_structure_45.png | Bin 0 -> 24681 bytes img/data_structure_46.png | Bin 0 -> 14220 bytes img/data_structure_47.png | Bin 0 -> 7912 bytes img/data_structure_48.png | Bin 0 -> 4773 bytes img/data_structure_5.png | Bin 0 -> 11548 bytes img/data_structure_50.png | Bin 0 -> 35322 bytes img/data_structure_51.png | Bin 0 -> 35608 bytes img/data_structure_52.png | Bin 0 -> 28041 bytes img/data_structure_53.png | Bin 0 -> 36243 bytes img/data_structure_54.png | Bin 0 -> 35595 bytes img/data_structure_55.png | Bin 0 -> 38966 bytes img/data_structure_56.png | Bin 0 -> 37476 bytes img/data_structure_57.png | Bin 0 -> 42079 bytes img/data_structure_58.png | Bin 0 -> 18172 bytes img/data_structure_59.png | Bin 0 -> 55654 bytes img/data_structure_6.png | Bin 0 -> 27058 bytes img/data_structure_60.png | Bin 0 -> 11648 bytes img/data_structure_7.png | Bin 0 -> 47629 bytes img/data_structure_9.png | Bin 0 -> 5195 bytes img/doc.jpg | Bin 0 -> 40462 bytes img/exe_file.jpeg | Bin 0 -> 6312 bytes img/expression tree.png | Bin 0 -> 18184 bytes img/final_charts/1.png | Bin 0 -> 38535 bytes img/final_charts/10-4-1.png | Bin 0 -> 23158 bytes img/final_charts/10-4.png | Bin 0 -> 27766 bytes img/final_charts/10-8.png | Bin 0 -> 27766 bytes img/final_charts/11-4-1.png | Bin 0 -> 3704 bytes img/final_charts/11-4.png | Bin 0 -> 28938 bytes img/final_charts/11-8.png | Bin 0 -> 31804 bytes img/final_charts/12-4-1.png | Bin 0 -> 15301 bytes img/final_charts/12-4.png | Bin 0 -> 25943 bytes img/final_charts/12-8.png | Bin 0 -> 25527 bytes img/final_charts/13-4.png | Bin 0 -> 44275 bytes img/final_charts/13-8.png | Bin 0 -> 43228 bytes img/final_charts/14-4-1.png | Bin 0 -> 19729 bytes img/final_charts/14-4.png | Bin 0 -> 27390 bytes img/final_charts/14-8.png | Bin 0 -> 28560 bytes img/final_charts/15-4.png | Bin 0 -> 47915 bytes img/final_charts/15-8.png | Bin 0 -> 47783 bytes img/final_charts/2-4.png | Bin 0 -> 34832 bytes img/final_charts/2-8.png | Bin 0 -> 34625 bytes img/final_charts/4-4.png | Bin 0 -> 34438 bytes img/final_charts/4-8.png | Bin 0 -> 37356 bytes img/final_charts/5-4.png | Bin 0 -> 38235 bytes img/final_charts/5-8.png | Bin 0 -> 40644 bytes img/final_charts/6-4.png | Bin 0 -> 36130 bytes img/final_charts/6-8.png | Bin 0 -> 37473 bytes img/final_charts/7-4.png | Bin 0 -> 43081 bytes img/final_charts/7-8.png | Bin 0 -> 45537 bytes img/final_charts/8-4.png | Bin 0 -> 30156 bytes img/final_charts/8-8.png | Bin 0 -> 30926 bytes img/final_charts/9-4.png | Bin 0 -> 34424 bytes img/final_charts/9-8.png | Bin 0 -> 33952 bytes img/flowdiagram.png | Bin 0 -> 22711 bytes img/gdb/inf.jpeg | Bin 0 -> 217249 bytes img/gdb/infix_expression_tree.jpeg | Bin 0 -> 14048 bytes img/gdb/question.jpg | Bin 0 -> 5335 bytes img/gdb/root.jpeg | Bin 0 -> 4277 bytes img/gdb/start_ss.jpeg | Bin 0 -> 162896 bytes img/gdb/t1.jpeg | Bin 0 -> 7517 bytes img/gdb/t10.jpeg | Bin 0 -> 26546 bytes img/gdb/t11.jpeg | Bin 0 -> 28423 bytes img/gdb/t12.jpeg | Bin 0 -> 34002 bytes img/gdb/t13.jpeg | Bin 0 -> 30982 bytes img/gdb/t14.jpeg | Bin 0 -> 26862 bytes img/gdb/t15.jpeg | Bin 0 -> 25533 bytes img/gdb/t16.jpeg | Bin 0 -> 26090 bytes img/gdb/t2.jpeg | Bin 0 -> 8269 bytes img/gdb/t3.jpeg | Bin 0 -> 8508 bytes img/gdb/t4.jpeg | Bin 0 -> 11082 bytes img/gdb/t5.jpeg | Bin 0 -> 13718 bytes img/gdb/t6.jpeg | Bin 0 -> 21176 bytes img/gdb/t7.jpeg | Bin 0 -> 25681 bytes img/gdb/t8.jpeg | Bin 0 -> 27091 bytes img/gdb/t9.jpeg | Bin 0 -> 34156 bytes img/gsymboltable1.png | Bin 0 -> 10638 bytes img/gsymboltable2.png | Bin 0 -> 11296 bytes img/gsymboltable3.png | Bin 0 -> 19792 bytes img/header.png | Bin 0 -> 3989 bytes img/label-table.png | Bin 0 -> 8487 bytes img/left.png | Bin 0 -> 161 bytes img/lex_1.png | Bin 0 -> 13954 bytes img/lex_2.png | Bin 0 -> 9779 bytes img/lex_3.jpeg | Bin 0 -> 29227 bytes img/lex_4.png | Bin 0 -> 12368 bytes img/lex_5.png | Bin 0 -> 13556 bytes img/libcallstack.png | Bin 0 -> 1299 bytes img/libcallstack1.png | Bin 0 -> 1972 bytes img/loading.gif | Bin 0 -> 673 bytes img/localsymboltable1.png | Bin 0 -> 6840 bytes img/localsymboltable2.png | Bin 0 -> 6817 bytes img/logo.png | Bin 0 -> 1057 bytes img/logo1.png | Bin 0 -> 19285 bytes img/map.jpg | Bin 0 -> 17972 bytes img/memory_management.png | Bin 0 -> 7915 bytes img/memory_model_1.png | Bin 0 -> 9481 bytes img/nitc-logo.png | Bin 0 -> 25432 bytes img/process_model.png | Bin 0 -> 4338 bytes img/reg.png | Bin 0 -> 29983 bytes img/reg0after.png | Bin 0 -> 26513 bytes img/reg0before.png | Bin 0 -> 19164 bytes img/reg1.png | Bin 0 -> 33829 bytes img/regR05.png | Bin 0 -> 41342 bytes img/regR0R1.png | Bin 0 -> 44564 bytes img/rts11.png | Bin 0 -> 26590 bytes img/rts2.png | Bin 0 -> 18873 bytes img/runtimestackoexpl.png | Bin 0 -> 25733 bytes img/runtimestackoexpl2.png | Bin 0 -> 16214 bytes img/runtimestackoexpl2_1.png | Bin 0 -> 17435 bytes img/stack.png | Bin 0 -> 8382 bytes img/symboltable.png | Bin 0 -> 57186 bytes img/syscallstack.png | Bin 0 -> 1116 bytes img/syscallstack1.png | Bin 0 -> 1628 bytes img/system_call_interface_stack.png | Bin 0 -> 8866 bytes img/system_call_stack1.png | Bin 0 -> 10061 bytes img/system_call_stack2.png | Bin 0 -> 10121 bytes img/terminal.png | Bin 0 -> 71093 bytes img/tree1.png | Bin 0 -> 4579 bytes img/tree2.png | Bin 0 -> 9371 bytes img/tree3.png | Bin 0 -> 24351 bytes img/up.png | Bin 0 -> 145 bytes img/valid.png | Bin 0 -> 1259 bytes img/var-bind table.png | Bin 0 -> 6282 bytes img/virtual_function_table_1.png | Bin 0 -> 8594 bytes img/virtual_function_table_2.png | Bin 0 -> 26555 bytes img/virtual_function_table_3.png | Bin 0 -> 15035 bytes img/virtual_function_table_4.png | Bin 0 -> 97893 bytes img/virtual_function_table_5.png | Bin 0 -> 3975 bytes img/virtual_function_table_6.png | Bin 0 -> 3859 bytes img/virtual_function_table_7.png | Bin 0 -> 3851 bytes img/virtual_function_table_8.png | Bin 0 -> 6432 bytes img/yacc_1.jpg | Bin 0 -> 20663 bytes img/yacc_1.png | Bin 0 -> 21096 bytes img/yacc_2.jpg | Bin 0 -> 98726 bytes img/yacc_3.jpg | Bin 0 -> 52435 bytes img/yacc_4.jpg | Bin 0 -> 89505 bytes img/yacc_5.jpg | Bin 0 -> 46699 bytes img/yacc_6.jpg | Bin 0 -> 14915 bytes img/yacc_7.jpg | Bin 0 -> 14061 bytes img/ywl1.png | Bin 0 -> 565 bytes img/ywl10.png | Bin 0 -> 1367 bytes img/ywl11.png | Bin 0 -> 1003 bytes img/ywl12.png | Bin 0 -> 1367 bytes img/ywl13.png | Bin 0 -> 1003 bytes img/ywl14.png | Bin 0 -> 1480 bytes img/ywl15.png | Bin 0 -> 1003 bytes img/ywl16.png | Bin 0 -> 1477 bytes img/ywl17.png | Bin 0 -> 1076 bytes img/ywl18.png | Bin 0 -> 1908 bytes img/ywl19.png | Bin 0 -> 1514 bytes img/ywl2.png | Bin 0 -> 807 bytes img/ywl20.png | Bin 0 -> 2234 bytes img/ywl21.png | Bin 0 -> 1634 bytes img/ywl22.png | Bin 0 -> 2234 bytes img/ywl23.png | Bin 0 -> 1634 bytes img/ywl24.png | Bin 0 -> 2294 bytes img/ywl25.png | Bin 0 -> 1638 bytes img/ywl26.png | Bin 0 -> 2215 bytes img/ywl27.png | Bin 0 -> 1665 bytes img/ywl28.png | Bin 0 -> 2593 bytes img/ywl29.png | Bin 0 -> 1892 bytes img/ywl3.png | Bin 0 -> 722 bytes img/ywl30.png | Bin 0 -> 2590 bytes img/ywl31.png | Bin 0 -> 1873 bytes img/ywl32.png | Bin 0 -> 2695 bytes img/ywl33.png | Bin 0 -> 1864 bytes img/ywl34.png | Bin 0 -> 2772 bytes img/ywl35.png | Bin 0 -> 1923 bytes img/ywl36.png | Bin 0 -> 2174 bytes img/ywl37.png | Bin 0 -> 1590 bytes img/ywl38.png | Bin 0 -> 2307 bytes img/ywl39.png | Bin 0 -> 1785 bytes img/ywl4.png | Bin 0 -> 930 bytes img/ywl40.png | Bin 0 -> 2455 bytes img/ywl41.png | Bin 0 -> 1818 bytes img/ywl42.png | Bin 0 -> 1984 bytes img/ywl43.png | Bin 0 -> 1367 bytes img/ywl44.png | Bin 0 -> 2054 bytes img/ywl45.png | Bin 0 -> 1411 bytes img/ywl46.png | Bin 0 -> 1348 bytes img/ywl47.png | Bin 0 -> 985 bytes img/ywl48.png | Bin 0 -> 1334 bytes img/ywl49.png | Bin 0 -> 968 bytes img/ywl5.png | Bin 0 -> 776 bytes img/ywl50.png | Bin 0 -> 731 bytes img/ywl51.png | Bin 0 -> 613 bytes img/ywl52.png | Bin 0 -> 964 bytes img/ywl53.png | Bin 0 -> 853 bytes img/ywl54.png | Bin 0 -> 980 bytes img/ywl55.png | Bin 0 -> 912 bytes img/ywl56.png | Bin 0 -> 691 bytes img/ywl57.png | Bin 0 -> 592 bytes img/ywl6.png | Bin 0 -> 1037 bytes img/ywl7.png | Bin 0 -> 779 bytes img/ywl8.png | Bin 0 -> 1057 bytes img/ywl9.png | Bin 0 -> 825 bytes img/ywlexp0.png | Bin 0 -> 8935 bytes img/ywlexp1.png | Bin 0 -> 1304 bytes img/ywlexp10.png | Bin 0 -> 1480 bytes img/ywlexp11.png | Bin 0 -> 2370 bytes img/ywlexp12.png | Bin 0 -> 1477 bytes img/ywlexp13.png | Bin 0 -> 2175 bytes img/ywlexp14.png | Bin 0 -> 1655 bytes img/ywlexp15.png | Bin 0 -> 2706 bytes img/ywlexp16.png | Bin 0 -> 4214 bytes img/ywlexp17.png | Bin 0 -> 2608 bytes img/ywlexp18.png | Bin 0 -> 2162 bytes img/ywlexp19.png | Bin 0 -> 3171 bytes img/ywlexp2.png | Bin 0 -> 930 bytes img/ywlexp20.png | Bin 0 -> 2134 bytes img/ywlexp21.png | Bin 0 -> 3461 bytes img/ywlexp22.png | Bin 0 -> 5291 bytes img/ywlexp23.png | Bin 0 -> 3310 bytes img/ywlexp24.png | Bin 0 -> 4981 bytes img/ywlexp25.png | Bin 0 -> 9514 bytes img/ywlexp26.png | Bin 0 -> 2162 bytes img/ywlexp27.png | Bin 0 -> 11023 bytes img/ywlexp28.png | Bin 0 -> 2455 bytes img/ywlexp29.png | Bin 0 -> 13020 bytes img/ywlexp3.png | Bin 0 -> 1304 bytes img/ywlexp30.png | Bin 0 -> 1984 bytes img/ywlexp31.png | Bin 0 -> 3152 bytes img/ywlexp32.png | Bin 0 -> 1348 bytes img/ywlexp33.png | Bin 0 -> 10861 bytes img/ywlexp34.png | Bin 0 -> 731 bytes img/ywlexp35.png | Bin 0 -> 8136 bytes img/ywlexp36.png | Bin 0 -> 980 bytes img/ywlexp37.png | Bin 0 -> 8140 bytes img/ywlexp38.png | Bin 0 -> 982 bytes img/ywlexp4.png | Bin 0 -> 1037 bytes img/ywlexp5.png | Bin 0 -> 1739 bytes img/ywlexp6.png | Bin 0 -> 1057 bytes img/ywlexp7.png | Bin 0 -> 2314 bytes img/ywlexp8.png | Bin 0 -> 1367 bytes img/ywlexp9.png | Bin 0 -> 2314 bytes img/zoom.png | Bin 0 -> 3783 bytes index.html | 1 + install/index.html | 15 + label-translation/index.html | 420 ++ lex/index.html | 280 + libinterface/index.html | 2 + libinterfaceexpl/index.html | 1 + library-implementation/index.html | 22 + oexpl-data-structures/index.html | 93 + oexpl-grammar-outline/index.html | 165 + oexpl-run-data-structures/index.html | 164 + oexpl-runtime-binding-tutorial/index.html | 93 + oexpl-specification/index.html | 140 + oexpl-testprograms/index.html | 1 + oexpl/index.html | 1 + oexpl_data_structures/class-table/index.html | 93 + .../virtual_function_table/index.html | 72 + oexpltestprograms/test1/index.html | 132 + oexpltestprograms/test2/index.html | 88 + oexpltestprograms/test3/index.html | 57 + oexpltestprograms/test4/index.html | 68 + oexpltestprograms/test5/index.html | 97 + oexpltestprograms/test6/index.html | 76 + oexpltestprograms/test7/index.html | 99 + pdfs/expl.pdf | Bin 0 -> 205019 bytes roadmap/index.html | 1 + roadmap/stage-00/index.html | 1 + roadmap/stage-01/index.html | 31 + roadmap/stage-02/index.html | 28 + roadmap/stage-03/index.html | 60 + roadmap/stage-04/index.html | 67 + roadmap/stage-05/index.html | 81 + roadmap/stage-06/index.html | 34 + roadmap/stage-07/index.html | 2 + roadmap/stage-08/index.html | 12 + run-data-structures/index.html | 28 + run_data_structures/heap/index.html | 9 + run_data_structures/register/index.html | 1 + run_data_structures/run-time-stack/index.html | 28 + .../static-allocation/index.html | 1 + search/search_index.json | 1 + sitemap.xml | 418 + sitemap.xml.gz | Bin 0 -> 776 bytes testprograms/index.html | 1 + testprograms/stage4/bubblesort/index.html | 28 + testprograms/stage4/fibaofn/index.html | 21 + testprograms/stage4/prime/index.html | 22 + testprograms/stage4/sum-to-n-fact/index.html | 22 + testprograms/test-program-01/index.html | 39 + testprograms/test-program-02/index.html | 53 + testprograms/test-program-03/index.html | 54 + testprograms/test-program-04/index.html | 58 + testprograms/test-program-05/index.html | 36 + testprograms/test-program-06/index.html | 124 + testprograms/test-program-07/index.html | 32 + testprograms/test-program-08/index.html | 53 + testprograms/test-program-09/index.html | 108 + testprograms/test-program-10/index.html | 33 + testprograms/test-program-11/index.html | 102 + testprograms/test-program-12/index.html | 37 + xsm-environment-tut/index.html | 176 + xsmusagespec/index.html | 2 + yacc/index.html | 267 + ywl/index.html | 375 + 428 files changed, 12807 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 Data_Structures/index.html create mode 100644 abi/index.html create mode 100644 about/authors/index.html create mode 100644 about/license/index.html create mode 100644 about/philosophy/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.fe8b6f2b.min.js create mode 100644 assets/javascripts/bundle.fe8b6f2b.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/stylesheets/main.3cba04c6.min.css create mode 100644 assets/stylesheets/main.3cba04c6.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 attribute/index.html create mode 100644 codegen/index.html create mode 100644 data-structures/index.html create mode 100644 data_structures/abstract-syntax-tree/index.html create mode 100644 data_structures/global-symbol-table/index.html create mode 100644 data_structures/local-symbol-table/index.html create mode 100644 data_structures/type-table/index.html create mode 100644 docker-setup/index.html create mode 100644 documentation/index.html create mode 100644 ex1/index.html create mode 100644 expl/index.html create mode 100644 explusagespec/index.html create mode 100644 extra.css create mode 100644 feedback/index.html create mode 100644 feedback/nitc-winter-2017/index.html create mode 100644 feedback/nitc-winter-2021/index.html create mode 100644 files/xsm_expl.tar.gz create mode 100644 gdb-files/index.html create mode 100644 gdb/index.html create mode 100644 grammar-outline/index.html create mode 100644 help/index.html create mode 100644 img/2021_charts/1.png create mode 100644 img/2021_charts/2-1.png create mode 100644 img/2021_charts/3-1.png create mode 100644 img/2021_charts/4-1.png create mode 100644 img/2021_charts/5-1.png create mode 100644 img/2021_charts/6-1.png create mode 100644 img/2021_charts/7-1.png create mode 100644 img/GitHub-Logo.png create mode 100644 img/after call.png create mode 100644 img/architecturemodel.png create mode 100644 img/ast3.png create mode 100644 img/ast31.png create mode 100644 img/ast_stage2.png create mode 100644 img/ast_stage4.png create mode 100644 img/before call.png create mode 100644 img/class_table_1.png create mode 100644 img/class_table_2.png create mode 100644 img/codegen.png create mode 100644 img/compiler.gif create mode 100644 img/creativecommons.png create mode 100644 img/data_structure_1.png create mode 100644 img/data_structure_10.png create mode 100644 img/data_structure_11.png create mode 100644 img/data_structure_12.png create mode 100644 img/data_structure_13.png create mode 100644 img/data_structure_14.png create mode 100644 img/data_structure_15.png create mode 100644 img/data_structure_16.png create mode 100644 img/data_structure_17.png create mode 100644 img/data_structure_18.png create mode 100644 img/data_structure_19.png create mode 100644 img/data_structure_2.png create mode 100644 img/data_structure_20.png create mode 100644 img/data_structure_21.png create mode 100644 img/data_structure_22.png create mode 100644 img/data_structure_23.png create mode 100644 img/data_structure_24.png create mode 100644 img/data_structure_25.png create mode 100644 img/data_structure_26.png create mode 100644 img/data_structure_27.png create mode 100644 img/data_structure_28.png create mode 100644 img/data_structure_29.png create mode 100644 img/data_structure_3.png create mode 100644 img/data_structure_31.png create mode 100644 img/data_structure_32.png create mode 100644 img/data_structure_33.png create mode 100644 img/data_structure_34.png create mode 100644 img/data_structure_35.png create mode 100644 img/data_structure_36.png create mode 100644 img/data_structure_37.png create mode 100644 img/data_structure_38.png create mode 100644 img/data_structure_39.png create mode 100644 img/data_structure_4.png create mode 100644 img/data_structure_40.png create mode 100644 img/data_structure_41.png create mode 100644 img/data_structure_42.png create mode 100644 img/data_structure_43.png create mode 100644 img/data_structure_44.png create mode 100644 img/data_structure_45.png create mode 100644 img/data_structure_46.png create mode 100644 img/data_structure_47.png create mode 100644 img/data_structure_48.png create mode 100644 img/data_structure_5.png create mode 100644 img/data_structure_50.png create mode 100644 img/data_structure_51.png create mode 100644 img/data_structure_52.png create mode 100644 img/data_structure_53.png create mode 100644 img/data_structure_54.png create mode 100644 img/data_structure_55.png create mode 100644 img/data_structure_56.png create mode 100644 img/data_structure_57.png create mode 100644 img/data_structure_58.png create mode 100644 img/data_structure_59.png create mode 100644 img/data_structure_6.png create mode 100644 img/data_structure_60.png create mode 100644 img/data_structure_7.png create mode 100644 img/data_structure_9.png create mode 100644 img/doc.jpg create mode 100644 img/exe_file.jpeg create mode 100644 img/expression tree.png create mode 100644 img/final_charts/1.png create mode 100644 img/final_charts/10-4-1.png create mode 100644 img/final_charts/10-4.png create mode 100644 img/final_charts/10-8.png create mode 100644 img/final_charts/11-4-1.png create mode 100644 img/final_charts/11-4.png create mode 100644 img/final_charts/11-8.png create mode 100644 img/final_charts/12-4-1.png create mode 100644 img/final_charts/12-4.png create mode 100644 img/final_charts/12-8.png create mode 100644 img/final_charts/13-4.png create mode 100644 img/final_charts/13-8.png create mode 100644 img/final_charts/14-4-1.png create mode 100644 img/final_charts/14-4.png create mode 100644 img/final_charts/14-8.png create mode 100644 img/final_charts/15-4.png create mode 100644 img/final_charts/15-8.png create mode 100644 img/final_charts/2-4.png create mode 100644 img/final_charts/2-8.png create mode 100644 img/final_charts/4-4.png create mode 100644 img/final_charts/4-8.png create mode 100644 img/final_charts/5-4.png create mode 100644 img/final_charts/5-8.png create mode 100644 img/final_charts/6-4.png create mode 100644 img/final_charts/6-8.png create mode 100644 img/final_charts/7-4.png create mode 100644 img/final_charts/7-8.png create mode 100644 img/final_charts/8-4.png create mode 100644 img/final_charts/8-8.png create mode 100644 img/final_charts/9-4.png create mode 100644 img/final_charts/9-8.png create mode 100644 img/flowdiagram.png create mode 100644 img/gdb/inf.jpeg create mode 100644 img/gdb/infix_expression_tree.jpeg create mode 100644 img/gdb/question.jpg create mode 100644 img/gdb/root.jpeg create mode 100644 img/gdb/start_ss.jpeg create mode 100644 img/gdb/t1.jpeg create mode 100644 img/gdb/t10.jpeg create mode 100644 img/gdb/t11.jpeg create mode 100644 img/gdb/t12.jpeg create mode 100644 img/gdb/t13.jpeg create mode 100644 img/gdb/t14.jpeg create mode 100644 img/gdb/t15.jpeg create mode 100644 img/gdb/t16.jpeg create mode 100644 img/gdb/t2.jpeg create mode 100644 img/gdb/t3.jpeg create mode 100644 img/gdb/t4.jpeg create mode 100644 img/gdb/t5.jpeg create mode 100644 img/gdb/t6.jpeg create mode 100644 img/gdb/t7.jpeg create mode 100644 img/gdb/t8.jpeg create mode 100644 img/gdb/t9.jpeg create mode 100644 img/gsymboltable1.png create mode 100644 img/gsymboltable2.png create mode 100644 img/gsymboltable3.png create mode 100644 img/header.png create mode 100644 img/label-table.png create mode 100644 img/left.png create mode 100644 img/lex_1.png create mode 100644 img/lex_2.png create mode 100644 img/lex_3.jpeg create mode 100644 img/lex_4.png create mode 100644 img/lex_5.png create mode 100644 img/libcallstack.png create mode 100644 img/libcallstack1.png create mode 100644 img/loading.gif create mode 100644 img/localsymboltable1.png create mode 100644 img/localsymboltable2.png create mode 100644 img/logo.png create mode 100644 img/logo1.png create mode 100644 img/map.jpg create mode 100644 img/memory_management.png create mode 100644 img/memory_model_1.png create mode 100644 img/nitc-logo.png create mode 100644 img/process_model.png create mode 100644 img/reg.png create mode 100644 img/reg0after.png create mode 100644 img/reg0before.png create mode 100644 img/reg1.png create mode 100644 img/regR05.png create mode 100644 img/regR0R1.png create mode 100644 img/rts11.png create mode 100644 img/rts2.png create mode 100644 img/runtimestackoexpl.png create mode 100644 img/runtimestackoexpl2.png create mode 100644 img/runtimestackoexpl2_1.png create mode 100644 img/stack.png create mode 100644 img/symboltable.png create mode 100644 img/syscallstack.png create mode 100644 img/syscallstack1.png create mode 100644 img/system_call_interface_stack.png create mode 100644 img/system_call_stack1.png create mode 100644 img/system_call_stack2.png create mode 100644 img/terminal.png create mode 100644 img/tree1.png create mode 100644 img/tree2.png create mode 100644 img/tree3.png create mode 100644 img/up.png create mode 100644 img/valid.png create mode 100644 img/var-bind table.png create mode 100644 img/virtual_function_table_1.png create mode 100644 img/virtual_function_table_2.png create mode 100644 img/virtual_function_table_3.png create mode 100644 img/virtual_function_table_4.png create mode 100644 img/virtual_function_table_5.png create mode 100644 img/virtual_function_table_6.png create mode 100644 img/virtual_function_table_7.png create mode 100644 img/virtual_function_table_8.png create mode 100644 img/yacc_1.jpg create mode 100644 img/yacc_1.png create mode 100644 img/yacc_2.jpg create mode 100644 img/yacc_3.jpg create mode 100644 img/yacc_4.jpg create mode 100644 img/yacc_5.jpg create mode 100644 img/yacc_6.jpg create mode 100644 img/yacc_7.jpg create mode 100644 img/ywl1.png create mode 100644 img/ywl10.png create mode 100644 img/ywl11.png create mode 100644 img/ywl12.png create mode 100644 img/ywl13.png create mode 100644 img/ywl14.png create mode 100644 img/ywl15.png create mode 100644 img/ywl16.png create mode 100644 img/ywl17.png create mode 100644 img/ywl18.png create mode 100644 img/ywl19.png create mode 100644 img/ywl2.png create mode 100644 img/ywl20.png create mode 100644 img/ywl21.png create mode 100644 img/ywl22.png create mode 100644 img/ywl23.png create mode 100644 img/ywl24.png create mode 100644 img/ywl25.png create mode 100644 img/ywl26.png create mode 100644 img/ywl27.png create mode 100644 img/ywl28.png create mode 100644 img/ywl29.png create mode 100644 img/ywl3.png create mode 100644 img/ywl30.png create mode 100644 img/ywl31.png create mode 100644 img/ywl32.png create mode 100644 img/ywl33.png create mode 100644 img/ywl34.png create mode 100644 img/ywl35.png create mode 100644 img/ywl36.png create mode 100644 img/ywl37.png create mode 100644 img/ywl38.png create mode 100644 img/ywl39.png create mode 100644 img/ywl4.png create mode 100644 img/ywl40.png create mode 100644 img/ywl41.png create mode 100644 img/ywl42.png create mode 100644 img/ywl43.png create mode 100644 img/ywl44.png create mode 100644 img/ywl45.png create mode 100644 img/ywl46.png create mode 100644 img/ywl47.png create mode 100644 img/ywl48.png create mode 100644 img/ywl49.png create mode 100644 img/ywl5.png create mode 100644 img/ywl50.png create mode 100644 img/ywl51.png create mode 100644 img/ywl52.png create mode 100644 img/ywl53.png create mode 100644 img/ywl54.png create mode 100644 img/ywl55.png create mode 100644 img/ywl56.png create mode 100644 img/ywl57.png create mode 100644 img/ywl6.png create mode 100644 img/ywl7.png create mode 100644 img/ywl8.png create mode 100644 img/ywl9.png create mode 100644 img/ywlexp0.png create mode 100644 img/ywlexp1.png create mode 100644 img/ywlexp10.png create mode 100644 img/ywlexp11.png create mode 100644 img/ywlexp12.png create mode 100644 img/ywlexp13.png create mode 100644 img/ywlexp14.png create mode 100644 img/ywlexp15.png create mode 100644 img/ywlexp16.png create mode 100644 img/ywlexp17.png create mode 100644 img/ywlexp18.png create mode 100644 img/ywlexp19.png create mode 100644 img/ywlexp2.png create mode 100644 img/ywlexp20.png create mode 100644 img/ywlexp21.png create mode 100644 img/ywlexp22.png create mode 100644 img/ywlexp23.png create mode 100644 img/ywlexp24.png create mode 100644 img/ywlexp25.png create mode 100644 img/ywlexp26.png create mode 100644 img/ywlexp27.png create mode 100644 img/ywlexp28.png create mode 100644 img/ywlexp29.png create mode 100644 img/ywlexp3.png create mode 100644 img/ywlexp30.png create mode 100644 img/ywlexp31.png create mode 100644 img/ywlexp32.png create mode 100644 img/ywlexp33.png create mode 100644 img/ywlexp34.png create mode 100644 img/ywlexp35.png create mode 100644 img/ywlexp36.png create mode 100644 img/ywlexp37.png create mode 100644 img/ywlexp38.png create mode 100644 img/ywlexp4.png create mode 100644 img/ywlexp5.png create mode 100644 img/ywlexp6.png create mode 100644 img/ywlexp7.png create mode 100644 img/ywlexp8.png create mode 100644 img/ywlexp9.png create mode 100644 img/zoom.png create mode 100644 index.html create mode 100644 install/index.html create mode 100644 label-translation/index.html create mode 100644 lex/index.html create mode 100644 libinterface/index.html create mode 100644 libinterfaceexpl/index.html create mode 100644 library-implementation/index.html create mode 100644 oexpl-data-structures/index.html create mode 100644 oexpl-grammar-outline/index.html create mode 100644 oexpl-run-data-structures/index.html create mode 100644 oexpl-runtime-binding-tutorial/index.html create mode 100644 oexpl-specification/index.html create mode 100644 oexpl-testprograms/index.html create mode 100644 oexpl/index.html create mode 100644 oexpl_data_structures/class-table/index.html create mode 100644 oexpl_runtime_data_structures/virtual_function_table/index.html create mode 100644 oexpltestprograms/test1/index.html create mode 100644 oexpltestprograms/test2/index.html create mode 100644 oexpltestprograms/test3/index.html create mode 100644 oexpltestprograms/test4/index.html create mode 100644 oexpltestprograms/test5/index.html create mode 100644 oexpltestprograms/test6/index.html create mode 100644 oexpltestprograms/test7/index.html create mode 100644 pdfs/expl.pdf create mode 100644 roadmap/index.html create mode 100644 roadmap/stage-00/index.html create mode 100644 roadmap/stage-01/index.html create mode 100644 roadmap/stage-02/index.html create mode 100644 roadmap/stage-03/index.html create mode 100644 roadmap/stage-04/index.html create mode 100644 roadmap/stage-05/index.html create mode 100644 roadmap/stage-06/index.html create mode 100644 roadmap/stage-07/index.html create mode 100644 roadmap/stage-08/index.html create mode 100644 run-data-structures/index.html create mode 100644 run_data_structures/heap/index.html create mode 100644 run_data_structures/register/index.html create mode 100644 run_data_structures/run-time-stack/index.html create mode 100644 run_data_structures/static-allocation/index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 testprograms/index.html create mode 100644 testprograms/stage4/bubblesort/index.html create mode 100644 testprograms/stage4/fibaofn/index.html create mode 100644 testprograms/stage4/prime/index.html create mode 100644 testprograms/stage4/sum-to-n-fact/index.html create mode 100644 testprograms/test-program-01/index.html create mode 100644 testprograms/test-program-02/index.html create mode 100644 testprograms/test-program-03/index.html create mode 100644 testprograms/test-program-04/index.html create mode 100644 testprograms/test-program-05/index.html create mode 100644 testprograms/test-program-06/index.html create mode 100644 testprograms/test-program-07/index.html create mode 100644 testprograms/test-program-08/index.html create mode 100644 testprograms/test-program-09/index.html create mode 100644 testprograms/test-program-10/index.html create mode 100644 testprograms/test-program-11/index.html create mode 100644 testprograms/test-program-12/index.html create mode 100644 xsm-environment-tut/index.html create mode 100644 xsmusagespec/index.html create mode 100644 yacc/index.html create mode 100644 ywl/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..9869883 --- /dev/null +++ b/404.html @@ -0,0 +1 @@ +
The compilation/interpretation of an ExpL program involves two phases. In the first phase (called the analysis phase), the source ExpL program is analyzed (lexical, syntax and semantic analysis are completed in this phase) and if the program is free of syntax and semantic errors, an intermediate representation of the source program called the abstract syntax tree is generated.
This is followed by a second phase, whose functionality is different for a compiler and an interpreter.
In the case of a compiler, the second phase (called the synthesis phase) recursively traverses the abstract syntax tree and generates target code.
[Note: the abstract syntax tree representation is only one among several intermediete representations used in practical compilers. “Lower level” intermediete representations like three address code are often more useful for applying code optimization algorithms. In our present experiment, we do not perform any code optimizations and hence the code generation phase will directly work with the abstract syntax tree.]
In the case of interpretation, the second phase (called the execution phase) involves direct execution of the program by recursive evaluation of the abstract syntax tree.
The description of data structures below assumes an interpreter is being designed. This choice has been made to avoid target machine dependency in the documentation. Notes/comments are added wherever appropriate explaining the modifications to be made to the data structures to implement a compiler.
There are three basic data structures that are maintained during the analysis phase. These are the following:
An abstract syntax tree is a tree representation of a program. It is a generalization of the tree representation for expressions (called the expression tree). For example, the arithmetic expression (3+5)*(5+9) is typically represented as an expression tree as below:
We can generalize this representation to come up with a tree representation for the whole sequence of statements of a ExpL function in a program. Each funcion in an ExpL program will be represented by an abstract syntax tree. Thus, the whole program will be a collection of abstract syntax trees, one for each function.
In the following, the definitions node structures for each of the above data structures is discussed. The organization of data in these data structures is also discussed with illustrative examples.
The Type Table stores all the necessary information regarding the various user defined types in the source program. The compiler creates an entry in the Type Table for each user defined type. In addition to this, there are default entries created for primitive types (int, str) and special entries null, boolean and void for the internal purposes of the interpreter. The default and special entries are made beforehand whereas entries for user defined types are made as the Type Declaration Section of the source code is parsed.
The structure of Type Table is as follows:
The variable 'fields' is a pointer to the head of 'fieldlist'. Here 'fieldlist' stores the information regarding the different fields in the case of a user-defined type.
Let us consider the following sample code:
The type table is first created and initialised to contain the default entries for each of the primitive and internal datatypes. This is done through a call to the function TypeTableCreate() from main function before yyparse() is called to start parsing the code. After the execution of TypeTableCreate() , the type table will be as follows:
As soon as the compiler encounters the declaration of a user defined type, it is installed into the type table. Subsequently the fields are attached to this type table entry. For instance, in the case of the user-defined type linkedlist, as soon as the name linkedlist is encountered, a type table entry with 'name' set to linkedlist and 'fields' set to NULL is created. Later, on finishing the complete parse of the type definition, the fieldlist is created and it is attached to the type table entry.
NOTE : A type table entry is created as soon as the type name is seen. This is because a field of the type may be of same type (For example, just like next is of type linkedlist in the type definition of linkedlist). When the 'fieldlist' is created, the type of the field is set by looking up the type table.
Similar actions are carried out for user-defined type marklist also.
Once the type declaration section is completely parsed, the type table is fully created and will not be further modified or updated.
Symbol tables are used to store information pertaining to the variables and functions in a program.
The global symbol table stores information pertaining to all the global variables and functions in an ExpL program.
The structure of Global Symbol Table(GST) is as follows:
✛NOTE: In the case of a compiler, fbinding must store the starting address of the function's code in memory. A call to the function must translate into an assembly level call to the function's code in memory. Hence, in this case fbining has to be an integer storing a memory address.
Arglist is used to store information regarding the types and names of the arguements. ArgStruct has the following structure.
Read about ASTNode here.
Continuing with earlier example, let us add Global declaration section to it.
In addition to the global symbol table, the ExpL compiler maintains a separate local symbol table for each function for storing information regarding the functions arguments and local variables. Each function has its own list of local variables. So each function has its own LST.
Arrays cannot be local variables, so we don't need to store the size of a variables. Also nested functions are not allowed in ExpL, so we don't require fbinding and arglist as in Gsymbol. The LST is formed for the Local Declaration Section in the same way GST was created for the Global declaration section.
Memory is allocated for local variables of a function from a seperate memory area called the stack. Hence, the binding for a local variable is the relative address of the variable with respect to the base of the [Activation Record]. The [Base Pointer] points to the base of an activation record of a function. The binding is added to the Base Pointer to obtain the address of variable in stack. This will be explained in detail later.
The machine independent front-end phase of a compiler constructs an intermediate representation of the source program called the Abstract Syntax Tree (AST). An interpretter will evaluate the AST whereas a compiler will run a machine dependent back-end to generate a target assembly language program. The following structure may be used to represent a node of the AST.
The union Constant is used to store the value of an integer or sting constant.
regindex evaluate(struct ASTNode *t)
Evaluation of an AST node results in a value. A compiler generates code for evaluating an AST node and assigns the result of evaluation to a register. An interpreter directly evaluates the AST node and simulates the compiler by storing the result in an array (called reg) and returning the index. We make use of the following structure to store the results of evaluation by an interpreter:
In 'valstruct' the field 'valtype' can take one of the following values:
Follwing are the nodetypes that may appear while contructing the abstract syntax free for ExpL program:
Nodetype
Description
LEAF
For interger and string constants.
ID
For all variable literals.
PLUS
For arithmetic operator '+'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
'ptr3' is set to NULL.
MINUS
For arithmetic operator '-'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
'ptr3' is set to NULL.
MUL
For arithmetic operator '*'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
DIV
For arithmetic operator '/'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
GT
For relational operator '>'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
LT
For relational operator '<'.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
GE
For relational operatot '>='.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
LE
For relational operatot '<='.
Attributes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and must be of type 'int'.
EQ
For relational operator '=='.
Attricutes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and both must be of same type.
NE
For relational operator '!='.
Attricutes 'ptr1' and 'ptr2' of the 'ASTNode' are set to AST of left and right operands respectively and both must be of same type.
IF
For the conditional contruct 'if'.
Attribute 'ptr1' of the 'ASTNode' is set to AST of the conditional logical expression, 'ptr2' is set to AST of list of statements that are executed when conditional expression evaluates to true and 'ptr3' is set to AST of list of statements that are to be executed when conditional expression is evalusted false.
WHILE
For conditional construct 'while'.
Attribute 'ptr1' os 'ASTNode' is set to the conditional logical expression and 'ptr2' is set to AST of list of statements under the while construct.
READ
For input statement 'read'. Attribute 'ptr1' is set to AST of nodetype ID, which carries the information of the variable for which we are taking the input.
WRITE
For output statement 'write'. Attibute 'ptr1' is set to AST of the expression, whose value is to be written to the standard output.
ASGN
For assignment statement ( =
Attribute 'ptr1' is set to AST of nodetype ID or FIELD and 'ptr2' is set to AST of expression whose value will be assigned to lvalue given by 'ptr1'.
SLIST
To connect statements.
BODY
For body of a function.
RET
For return statement of a function.
FUNCTION
For function calls.
PARAM
For passing actual parameters during function calls.
MAIN
For main function.
FIELD
For user-defined types.
Consider the following program
1. Lets construct the abstract syntax tree step by step. The AST for conditional expression n==1
(in line 9) will be as follows:
2. Similarly we have AST fot n==0
(in line 9) as follows.
3. Next consider the complete conditional expression n==1 || n==0
.
4.Next we will form the AST for assignment statement f = 1
(in line 10).
5. Next, lets consider the statement f = n * factorial(n-1)
which consists of arthimetic expressions with operands '-','*' and an assignment statement.
AST for n-1
is as follows.
AST for n * factorial(n-1)
is as follows.
AST for f = n * factorial(n-1)
is as below.
6. Following is the AST for the if condition.
7. The AST for return statement is as folows
8. Finally the AST for the factorial function will be as follows.
Before explaining the data structures used for the execution phase, it is necessary to understand the requirements and the underlying theoretical concepts in some detail.
This part of the documentation primarily focuses on program interpretation. However, our interpreter will be somewhat mimicing the actions of a compiler and hence the reader will be able to easily adapt what is learned here to handle the synthesis phase of compilation by going through this documentation.
An interpreter needs to "execute" the abstract syntax tree and hence the interpreter must arrange storage for run time data and subroutine invocations (function calls).
A program contains global variables as well as variables that are local to functions, both requiring memory space. Of these, global variables are the simplest to handle because during the analysis phase we know how many global variables are there in the program (all global variables are declared) and how much space needs to be allocated for each of them (why?). Thus, the storage requirements of global variables are completely determined at compile time and they can be assigned memory addresses during the analysis phase itself. Such allocation is called static allocation. The binding field of the global symbol table entry for a variable stores a pointer (address) to the memory allocated to the variable. The symbol table information will be used during the execution phase to find out the location in memory where the variable is stored.
[In the case of compilation, the memory addresses for each global variable in the target machine is determined during the analysis phase and are stored in the binding field of the symbol table.]
As a point aside, the binding field of the symbol table entry for a function is set to hold a pointer to the abstract syntax tree of the function. This helps the evaluation phase to locate the corresponding abstract syntax tree whenever a function call is encountered during the execution phase.
[In the case of a compiler, the the analysis phase will decide on the addresses in the code area of memory where the function's code is loaded. The address to which a call to the function must be directed to is stored in the binding field of the symbol table.]
Variables which are local to functions demands more complicated allocation. This is because a function may be invoked several times and for each invocation, separate storage needs to be allocated for variables defined within the scope of the function (i.e., local variables and arguments). [Why?] Moreover, we do not know during the analysis phase how many times a function will be invoked during the execution phase. [Why?]
To understand this, consider the factorial program below.
The function factorial contains an argument n. Suppose the initial value of n input by the user at run time was 5, then factorial(n) with n=5 is invoked from the main. This function invokes factorial(n) with n=4. However, we need to retain the old value of n since the orginal factorial function must resume execution after the completion of factorial(4). Thus, we cannot statically assign a fixed memory address to the variable n. Instead, for each invocation of the function, we need to create a different memory space for storing the value of n. Moreover, the initial value of n given by the user is not known at compile time. Hence cannot determine at compile time the exact storage requirement. We will have to design the compiler/interpreter to allocate memory space as is necessary during run time.
In addition to allocating storage for local variables and arguments, additional storage needs to be allocated at run time for each invocation of a function to store the return values of the call and control information like a pointer to the next instruction in the calling function (return address)].
The classical solution to handling function invocation is to maintain a run time stack. Whenever a function is invoked during execution, an activation record is created in the run time stack with sufficient space for storing local variables, arguments, return values and return address and the stack grows. Upon return from the function, the activation record is popped out of the stack and the activation record of the calling program will be in the top of the stack. Thus, at each point during execution, the activation record of the currently executing function will be on the top of the stack. Such storage allocation is called stack based run time allocation.
[Note: The semantics of ExpL makes stack based allocation possible. Primarily, this is possible because data stored in an activation record can be forgotten once the execution of the call is finished. There are languages like LISP which permit higher order functions where a stack based run time allocation is not possible. Languages which permit stack based run time allocation for function invocations are said to follow stack discipline.]
Observe that for each function defined in an ExpL program, the amount of storage needed in its activation record is known during the analysis phase. [Why?] What is not known is how many activation records will have to be created in the stack as this is known only during execution time.
In addition to allocating storage for global variables and variables local to functions, ExpL supports dynamic memory allocation through the alloc() function. The alloc() function allows a program to request for memory space at run time. Since the amount of memory requested is not known during the analysis phase (why?), static allocation is not possible in this case. Stack allocation also is ruled out because memory allocated by alloc() inside a function is not de-allocated when the function returns. Hence, a mechanism to dynamically allocate memory on demand at run time is required.
The classical solution to this problem is to maintain an contiguous area of memory called the heap memory from which memory is allocated by alloc() on demand. Heap management algorithms like the fixed size allocator algorithm and the buddy system algorithm are explained in detail later in this documentation.
Finally, intermediate values generated during program execution needs temporary storage. For example, while evaluating an expression (a+b)*(c+d), the values of the sub-expressions (a+b) and (c+d) might need temporary storage. In a compiler, the machine registers are used for temporary storage. Our interpreter will simulate the compiler by having an array of “registers” for storing such temporary values. When a function invokes another function, the registers in current use will be pushed to the stack (activation record of the caller) so that the called function (callee) has the full set of registers free for its use. Upon return from the callee, the values pushed into the stack are restored to the registers before the caller resumes its execution.
To summarize, we have four kinds of memory allocation – static, stack, heap and register (temporary). The data structures and algorithms necessary for implementing each of these are discussed below.
Our interpreter will simulate machine memory and registers by defining three memory arrays, named stack, heap and registers.
The basic unit of memory (called a memory word) is assumed to be able to store an integer or a string. This model is assumed because the primitive data types of ExpL are integer and string. The interpreter therefore defines the following memory structure:
The interpreter works with three arrays of memory words, to implement temporary storage (registers), the run time stack and the heap. There will be no sperarate memory array for static data. Instead, the intial part of the stack will be used for storing static data.
Register allocation is performed through two simple functions.
The interpreter invokes these functions in the course of evalaution of expressions to create temporary store.
As noted previously, global variables are allocated statically. In our interpreter, the initial portion of the stack will be used for static allocation. The rest of the stack memory region will be used for run time allocation. The amount of static storage required is known from the variable declarations.
During run-time, when an ExpL function is invoked, space has to be allocated for storing
For this, an activation record is created in the stack for each function call (and the stack grows). The activation record is also used to save the state (registers in use) of the invoking function and some control information (like the return address of the calling program in the case of a compiler).
Each activation record has a base, and the base pointer (BP) is a variable (or a machine register in the case of a compiler) that points to the base of the current functions activation record. When one function invokes another, the base pointer value of the caller is pushed on to the stack and BP is set to point to the new activation record base. Upon return, the activation record is popped off the stack and old value of base pointer is restored. The stack pointer (SP) points to the top of the stack.
The calling convension fixes in what order arguments to a function must be pushed by the caller to the called function, the place in the activation record where the return value is expected to be written by the callee etc. The structure of the activation record explained below will clarify the calling convension.
When a function is invoked, a part of the activation record is set up by the caller and the rest is set up after invocation of the function. Similarly, when a function returns, the callee and the caller are responsible for removing the parts they have set up.
The following sequence of actions occur when a function A calls another function B.
Inside B, the following space allocations take place:
This completes the activation record for B. If B later calls another function C, then it starts saving its registers, pushes arguments to C and so on.
When B completes execution the following sequence of actions take place:
On re-entry, A does the following:
Consider the following example:
The global variables are allocated statically in the initial portion of the stack.
The main functions sets up stack locations for its local variables and calls the function factorial(3) after setting up a part of the callee's activation record.
Factorial(3) saves the old Base pointer and sets up locations for its local variables.
Factorial(3) calls factorial(2) and the activation record of factorial(2) is setup similar to the above steps.
Activation record for factorial(1) (called by factorial(2)) is seup similarly.
factorial(1) calculates the result and returns it by setting the value at return value location and pops off it local variables and sets back the base pointer.
Similarly, factorial(2) calculates the steps and pops off its activation record till the result value after setting back the old base pointer.
Similarly, factorial(3) also calculates the result and returns it to the main function.
Main function calculates and sets the 'result' variable.
The stack is used to store data structures called activation records that are generated during procedure calls. An activation record is used to store the information such as value of program counter and machine registers when a function call occurs. When control returns from the function call, the activation of the calling procedure can be restarted after restoring the relevant registers and setting program counter to the point immediately after the call. Also, data of objects whose lifetime are contained in that of an activation can be allocated on the stack along with other information associated with activation.
So, for the implementation of the interpreter, we create a stack which is an array of memstruct. Memstruct has the following structure.
NOTE : for compiler, the stack structure and functions supported functions depends and is taken care of by the target machine.
The type field in memstruct can take the following values
NOTE : valstruct and memstruct structures have been used here to keep the fine line between a value object and a object in the memory.
A storage allocation decision can be static or dynamic. A decision is dynamic if it can be decided only while the program executes. In simple terms, consider the previous example, the size of the linkedlist marks is not known at the compile time, its size is only known at the run-time when we read in the count of subjects.
In interpreter, for heap we will be using an memstruct array of size 1024.
The two types of allocation-deallocation algorithms we will discuss here for heap management are fixed memory and buddy memory management.
In this algorithm, the chunk size allocated is fixed. Lets call the fixed size as HB_SIZE, say 8. The heap is considered here as a list of blocks of HB_SIZE.
The first block in the list is reserved. Initially, the first index of reserved block stores the index of first free block. The first index of every free block stores the index of next available free block. The last block stores -1 in the first index. This is how it looks initially(after the call to initialise function).
Following is the allocation algorithm.
Following is the pseudo code of the algorithm.
Following is the deallocation algorithm.
This section shows how the heap looks after each step of allocation or free. This is for the better understanding of the algorithms.
x = alloc();
x is a memstruct in the run-time stack of type MEMSTRUCT_BIND with intval 8.
y = alloc();
z = alloc();
dealloc(x);
dealloc(z);
z = alloc();
In this technique, memory is divided into partitions to try to satisfy a memory request as suitably as possible. This technique makes use of splitting memory into halves to give a best-fit.
Every memory block in this technique has an order, a number ranging from 0 to a specified upper limit. The size of block of order n is 2n. So the blocks are exacly twice the size of blocks of one order lower. Power-of-two block sizes makes address computation simple, because all buddies are aligned on memory address boundaries that are powers of two. When a larger block is split, it is divided into two smaller blocks, and each smaller block becomes a unique buddy to the other. A split block can only be merged with its unique buddy block, which then reforms the larger block they were split from.
Starting off, the size of the smallest possible block is determined, i.e. the smallest memory block that can be allocated. The smallest block size is then taken as the size of an order-0 block, so that all higher orders are expressed as power-of-two multiples of this size. In our implementation, we consider the smallest memory block size to be 8. So, the memory block sizes will be 8, 16, 32, 64, and so on. In our implementation, we take the heap of size 1024.
In our implementation, we have a heap of size 1024. The smallest block size possible in the heap is 8 (order 0). The highest block size of 2n that is free is 1024.We maintain a free list for all possible block sizes. So we have freelists for sizes 8,16,32,64,128,256,512 and 1024, i.e, we maintain eight freelists.
So, the size of the complete freelist is 20 + 20 + 21 + 22 + 23 + 24 + 25 +26 = 128.
We will maintain the freelist inside the heap, So initially we won't have the complete heap of 1024 free. So we need not require a freelist for size 1024. We will store the complete freelist in a 128 sized block. Therefore, initially we have the first 128 block(0-127) of the heap reserved for freelist maintainence. Then we have a 128 sized free block(128-255), then a 256 block(256-511) and then a free block of 512 size(512-1023). Following is the diagrammatic representation of the heap initial status.
The free-list in the heap has to be initialised as above. Also, the first index of each allocated block through alloc function will store the size of allocated block. This is to figure out the size that has been allocated when the dealloc function is called for a variable, which provides only the starting address of the block that has been allocated.
Following is the allocation algorithm : (argument : Request for a block of size 'A')
Following is the deallocation algorithm (arguement : the starting address of the allocated block)
The psuedo code for alloc and dealloc functions is as follows :
For a better understanding purpose, we will have a simple illustration of how heap memory looks like through a set of some allocations and deallocations.
For illustration, we will have 64-sized heap and smallest block size as 8. So we free lists for sizes 8,16 and 32 of lengths 4 ,2 and 1. So we will use a 8-size block to store the free-list.
The heap looks initially as follows.
Request for memory of size 5. Lets call this request as A. The nearest 2^k value for 5 is 8. We search for a 8 sized free block. We have one such! Allocate it!
Next we will have a reuqest B of size 14.
Now we have a request C of size 7.
Now, C releases its memory.
The ExpL compiler needs to translate a given source program and generate the target machine code into an executable file in a format which is recognized by the load module of the target operating system. Thus, in order to generate the executable, the following information needs to be made available to the compiler :
These specifications depend not only on the target machine architecture, but also on the operating system upon which the target machine code must execute. Typically these specifications are collected together in the OS specification into a document called the Application Binary Interface (ABI).
The following sections specify the ABI for the eXpOS operating system run on the XSM virtual machine model. The executable format is called the XEXE executable format.
The virtual machine model provided to user level programs by the ExpOS on the machine is described here. The virtual machine model explains the "view" of the machine provided to the application by the operating system.
The XSM virtual machine contains 20 general purpose registers (R0-R19) and three special registers - Stack pointer (SP), Base pointer (BP) and the Instruction pointer (IP). The SP register is normally used to point to the top of the application program's stack. The BP register is used to point to the base of the activation record of the currently executing function. IP points to the next instruction in the user memory to be fetched and executed. The memory address space available to the application is of 5120 words starting at (virtual) address 0 and ending at (virtual) address 5119.
The OS stipulates that this virtual address space must be divided into various regions called library, code, heap and stack. These will be described in detail later. The virtual machine model also allows the application to invoke traps to the operating system kernel for read, write and program termination (using the INT instruction). The details of the implementation of the kernel routines are hidden from the application and the application needs to know only the interface to invoke these routines. These interfaces will also be described later in this documentation.
The following figure gives a high level picture of the XSM virtual machine model.
The XSM virtual machine instruction set specifies the set of assembly level instructions. The compiler must translate the source ExpL program to a target program containing only these instructions. The assembly instructions allowed include Data Transfer Instructions, Arithmetic Instructions, Logical Instructions, Stack Instructions, Sub-routine instructions, Debug instructions and Software interrupts. The machine registers available to the target program are R0-R19, SP, BP and IP.
Addressing Type | Syntax | Semantics |
---|---|---|
Register Adressing | MOV Ri, Rj | Copies the contents of register Rj to Ri |
Immediate Addressing | MOV Ri, INTEGER/STRING | Copies the INTEGER/STRING to the register Ri |
Register Indirect Addressing | MOV Ri, [Rj] | Copy contents of memory location pointed by Rj to register Ri. |
MOV [Ri], Rj | Copy contents of Rj to the location whose address is in Ri | |
Direct Addressing | MOV [LOC], Rj | Copy contents of Rj to the memory address LOC |
MOV Rj, [LOC] | Copy contents of the memory location LOC to the register Rj |
Arithmetic Instructions perform arithmetic operations on registers containing integers. If the register contains a non-integer value, an exception (illegal instruction) is raised.
Instruction | Syntax | Semantics |
---|---|---|
ADD, SUB, MUL, DIV and MOD | OP Ri, Rj | The result of Ri op Rj is stored in Ri |
OP Ri, INTEGER | The result of Ri op INTEGER is stored in Ri | |
INR, DCR | OP Ri | Increments/Decrements the value of register Ri by 1 |
For all the above instructions, Ri/Rj may be any register except IP.
Logical instructions are used for comparing values in registers. Strings can also be compared according to the lexicographic ordering of ASCII. If one of the operands is a string, the other operand will also be considered as a string. The logical instructions are LT, GT, EQ, NE, GE and LE.
Type | Syntax | Semantics |
---|---|---|
LT, GT, EQ, NE, GE, LE | OP Ri, Rj | Stores 1 in Ri if the value stored in Ri is less than/greater than/equal to/not equal to/greater than or equal to/less than or equal to that in Rj. Ri is set to 0 otherwise |
Branching is achieved by changing the value of the IP to the word address of the target instruction specified by target_address
.
Type | Syntax | Semantics |
---|---|---|
JZ | JZ Ri, target_address | Jumps to target_address if the contents of Ri is zero |
JNZ | JNZ Ri, target_address | Jumps to target_address if the contents of Ri is not zero |
JMP | JMP target_address | Unconditional jump to target_address |
Type | Syntax | Semantics |
---|---|---|
PUSH | PUSH Ri | Increment SP by 1 and copy contents of Ri to the location pointed to by SP |
POP | POP Ri | Copy contents of the location pointed to by SP into Ri and decrement SP by 1 |
For both these instructions Ri may be any register except IP.
The CALL instruction copies the address of the next instruction to be fetched(this value must be IP + 2
since each instruction is two memory words) on to location SP + 1
. It also increments SP by one and transfers control to the instruction specified by the target_address
. The RET
instruction restores the IP value stored at location pointed by SP, decrements SP by one and continues execution fetching the next instruction pointed to by IP
Type | Syntax | Semantics |
---|---|---|
CALL | CALL target_address/ Register | Increments SP by 1, transfers IP + 2 to location pointed to by SP and jumps to instruction specified by target_address(or register containing the target address) |
RET | RET | Sets IP to the value pointed to by SP and decrements SP |
Syntax : BRKP Semantics : The machine when run in debug mode invokes the debugger when this intruction is executed. This instruction can be used for debugging system code.
Syntax : INT n Semantics : Generates an interrupt to the kernel with the interrupt number (n between 4 to 18) as an argument. The interrupt numbers relevant to the present project are given below.
System Call | Interrupt Routine Number |
---|---|
Read | 6 |
Write | 7 |
Exit | 10 |
The (virtual) address space of any eXpOS process is logically divided into four parts namely Library, Heap, Code and Stack.
The Library contains routines for implementing dynamic memory allocation functions Alloc()
, Free()
and Initialize()
as well as the input output functions Read()
and Write()
. The eXpOS loader links the library routines at load time when a program is loaded into the memory for execution. The compiler can therefore assume that the library code will be "there" at run-time and hence need not generate the code for implementing the library. The compiler however must generate code to invoke the correct library routines with appropriate arguments while translating the high level functions Alloc(), Free(), Initialize(), Read() and Write(). The ABI specifies how this must be done. Among these, Alloc(), Free() and Initialize() are implemented as part of the library itself. The library will re-direct Read() and Write() to low level OS system calls. (One of the advanced stages of the ExpL project will ask you to implement the library itself.) The ABI stipulates that eXpOS will load the library between addresses 0 and 1023 of the address space. Note that since each XSM instruction takes up two memory words, the library can be of size at most 512 instructions.
Heap is the portion of the address space reserved as the memory pool from which dynamic memory allocation is done by the allocator routine (Alloc() function) of the library. The memory region between addresses 1024 and 2047 is reserved for the heap. The routine Initialize()
will intialize the data structures associated with the memory allocator, Alloc() will allocate memory and Free() will de-allocate a previously allocated memory block. A discussion on dynamic memory allocation and de-allocation can be found here.
The Code region contains the target assembly language program generated by the compiler. The OS loader loads the contents of an XEXE executable file into this region (between memory addresses 2048 and 4095) of the address space. The loader expects that the first eight words of the XEXE executable file contains a header. The header contains instructions to the loader like the address of the first instruction to be executed (the loader will initalize the instruction pointer to this value before execution) and so on. The total size of the code section (including the 8 word header) cannot exceed 2048 words. Since each XSM instruction occupies two words in the memory, the maximum number of assembly instructions permitted in any target program generated by the compiler shall be 1020. Given an ExpL program as input, the job of the compiler is to generate an XEXE executable file containing the header and the target assembly language program.
Stack is the space reserved for the runtime stack of a program. Parameters and local variables associated with functions in a program are allocated in the stack. In the XSM architecture, the stack grows upwards. The eXpOS ABI stipulates that the maximum stack size is 1024 words. Global variables must be allocated in the stack as the eXpOS ABI does not support a separate Data region. The ABI stipulates that the compiler must allocate stack in the region between memory addresses 4095 and 5119 in the address space of the program. A discussion on how the compiler must allocate variables in the stack can be found here.
The compiler must generate target code into a file in the format specified below so that the eXpOS loader recognizes the format and load the program into memory for execution correctly. Each executable file contains a header in which the compiler adds information like the initial value to be given to the stack pointer in the virtual address space, initial value of the instruction pointer etc, the starting (virtual) addresses and sizes of various memory regions like text, stack, heap etc.
Executable files in eXpOS must be in the XEXE format as eXpOS executes only files of such format. An XEXE executable file in eXpOS consists of two parts:
The maximum size of the file (including the header) is limited by 2048 words.
The first eight words of an executable file are reserved for the header which describes the features of file. The structure of the header is :
XMAGIC is a number indicating the type of executable file. All XEXE files will have magic number 0. For more on Magic Number, click here.
Entry point contains the virtual address in memory of the first instruction to be executed (entry point) of the program after the OS loader has loaded it. During loading, the instruction pointer must be initialized to this address.
Text Size, Data Size, Heap Size and Stack size indicates the sizes of Text, Data, Heap and Stack regions to be allocated by the OS loader when the file is loaded for execution.
Note : The present eXpOS virtual address space model requires that the data and stack must be in the same memory area and must be managed by the compiler / application program (this means that the program must contain the code to initialize the value of the stack pointer). The value of Data Size field is ignored. Moreover, the eXpOS loader sets the size of text region to 2048 words and stack region to 1024 words in memory irrespective of the values present in the header.
If the Runtime Library must be included when the file is loaded, the Library Flag is set to 1 in the executable file. If this flag is not set then neither memory is allocated for the heap nor the library linked to the address space of the process at execution time.
In summary, the eXpOS loader maps an executable file into its virtual address according to the following table :
Region | Start Address | End Address |
---|---|---|
Library | 0 | 1023 |
Heap | 1024 | 2047 |
Code | 2048 | 4095 |
Stack | 4096 | 5119 |
The Stack Pointer is not initialised to the address 4096 by the eXpOS loader.
The library provides a uniform interface through which an application program can invoke dynamic memory allocation / de-allocation routines (Alloc(), Free() and Initialize()), input - output routines (Read() and Write()) and program exit (Exit()). Thus, while translating a high level ExpL program containing calls to the above functions, a compiler needs to be concerned only about how to translate these high level function calls to the corresponding library function calls.
The ABI stipulates that all calls to the library functions must be translated by the compiler to a CALL to virtual address 0, with an appropriate function code that identifies the service requested (Alloc(), Free(), Initalize(), Read(), Write() or Exit()). This is because the library is linked to virtual address 0 of the address space of a process by the OS loader. A call to the library requires four arguments (a function code to identify the service and three arguments) to be passed through the stack. The library will invoke the corresponding low level system call / memory managemen t routine and returns to the user program the return value of the system call / memory management routine through the stack. The figure above shows the contents of the stack immediately before a call to this library routine.
PUSH Function_Code // Push Function Code
+PUSH Argument_1 // Push argument 1 to the stack
+PUSH Argument_2 // Push argument 2 to the stack
+PUSH Argument_3 // Push argument 3 to the stack
+PUSH R0 // Push an empty space for RETURN VALUE
+CALL 0 // Pass the control to virtual address 0.
+ // (eXpOS loader links the library to virtual address 0)
+
A library module invocation using the high level application programmer's interface of a programming language like ExpL must be translated by the compiler to a set of machine instructions as given above.
Following are the library functions and details relevant for ExpL Compilation:
Library Function | Function Code | Argument 1 | Argument 2 | Argument 3 | Return Values |
---|---|---|---|---|---|
Read | "Read" | -1 | Buffer (int/str) | - | 0 - Success |
-1 - File Descriptor given is invalid | |||||
-2 - Read error | |||||
Write | "Write" | -2 | Data | - | 0 - Success |
-1 - File Descriptor given is invalid | |||||
Exit | "Exit" | - | - | - | - |
Initialize | "Heapset" | - | - | - | 0 - Success |
-1 - Failure | |||||
Alloc | "Alloc" | Size (int) | - | - | Address in the heap allocated (int) |
-1 - No allocation | |||||
Free | "Free" | Pointer (int) | - | - | 0 - Success |
-1 - Failure |
Note
The Read() library function expects a memory address from (or to) which read is performed.
Note
The Write() library function expects Data (final value to be printed) as argument.
The following machine instructions are present after the CALL instruction in the ExpL compiled machine code given in the previous step.
POP Ri // Pop and save the return value into some register Ri
+POP Rj // Pop and discard argument 3
+POP Rj // Pop and discard argument 2
+POP Rj // Pop and discard argument 1
+POP Rj // Pop and discard the function code
+ // Now the stack is popped back to the state before call
+
The machine code shown above is executed upon return from the library call and pops out the values that were pushed before the call. The function code and arguments were inputs to the library module and hence they may be discarded now. The return value which is stored in the stack by the system call must be popped out and saved to some register. This value will be the only relevant information after return from the call.
Note: The eXpOS library interface permits many more functions (interfaces to eXpOS system calls). Since these functions are not relevant for the implementation of the ExpL specification here, those details are left out. The full details of eXpOS library are given here.
The ExpL library file library.lib contains assembly instructions to implement the library functions Alloc()
, Free()
and Initialize()
. For the input/output functions Read()/Write() as well as the program exit system call Exit(), the library code invokes the corresponding ExpOS system calls for console read/write/exit. Thus, the library simply converts the library call to a low level call to the operating system. This is because console input/ouput functions are implemented at the OS level.
In order to implement the library, one must know the low level system call interface to the operating system so that the input/ouput calls to the library can be correctly translated to the corresponding low level OS system calls. This section specifices the low level OS interface provided by the ExpOS Operating System running on the XSM machine architecture. The interface describes the software interrupt instruction (trap) corresponding to the consolve input/output system calls and the calling conventions for passing arguments and extracting return values of the system call through the application program's stack. This part is architecture as well as operating system dependent.
For an application program, there are two stages in executing a system call:
A user program invokes a system call by first pushing the system call number and then the arguments into the stack and then invoking the INT machine instruction corresponding to the system call. The eXpOS ABI stipulates that the number of arguments pushed into the stack is fixed at three.
PUSH System_Call_Number // Push system call number
+PUSH Argument_1 // Push argument 1 to the stack
+PUSH Argument_2 // Push argument 2 to the stack
+PUSH Argument_3 // Push argument 3 to the stack
+PUSH R0 // Push an empty space for RETURN VALUE
+INT number // Invoke the corresponding INT instruction.
+ // The number can be any number between 4 and 18
+
The ExpL library must translate Read() and Write() calls to a set of machine instructions (see the instructions to the right). These are the stack operations that must be performed by the user program before the INT instruction is executed.
The arguments must be pushed into the stack in such a way that the last argument comes on the top. An additional push instruction ('PUSH R0') is inserted to have an empty space in the stack for the return value. The system call implementation stores the return value in this space. The system call number must be pushed to the stack before the call because the interrupt routine needs this value to identify the system call. The figure to the left shows the data stored in stack just before an INT instruction.
The INT instruction in XSM will push the value of IP + 2 on to the stack. This is the address of the instruction immediately following the INT instruction in the calling program. Each instruction is 2 words, hence IP is incremented by 2. Upon execution of the IRET instruction from the system call, execution resumes from this value of IP. The INT instruction changes mode from User mode to Kernel mode and passes control to the Interrupt Routine corresponding to the system call. The figure to the right shows the contents of the stack immediately after the execution of the INT instruction.
The IRET instruction transfers control back to the instruction that immediately follows the INT instruction. The following machine instructions are present after the INT instruction in the ExpL compiled machine code given in the previous step.
POP Ri // Pop and save the return value into some register Ri
+POP Rj // Pop and discard argument 3
+POP Rj // Pop and discard argument 2
+POP Rj // Pop and discard argument 1
+POP Rj // Pop and discard the system call number
+ // Now the stack is popped back to the state before call
+
The machine code to the left pops the values from the stack. The system call number and arguments were inputs to the system call and hence they may be discarded now. The return value which is stored in the stack by the system call is fetched and used by the user program by popping out to some register.
Associated with each system call, there is a system call number and interrupt routine number. The system call number is used to identify a system call. The interrupt routine number denotes the number of the interrupt routine which handles the system call.
System Call | System Call Number | Interrupt Routine Number | Argument 1 | Argument 2 | Argument 3 | Return Values |
---|---|---|---|---|---|---|
Read | 7 | 6 | -1 | Buffer (int/str) | - | 0 - Success |
-1 - File Descriptor given is invalid | ||||||
-2 - Read error | ||||||
Write | 5 | 7 | -2 | Data | - | 0 - Success |
-1 - File Descriptor given is invalid | ||||||
Exit | 10 | 10 | - | - | - | - |
Note
The Read() library function expects a memory address from (or to) which read is performed.
Note
The Write() library function expects Data (final value to be printed) as argument.
The content in the website and the documentation has been authored in the Department of Computer Science and Engineering, National Institute of Technology, Calicut under the guidance of Dr. Murali Krishnan K. The project's activity started in the year 2013 and completed in the year 2018. Below is a list of co-authors and contributors to the project. The work evolved from an earlier version of the project a Simple Integer Language Compiler development student project under the guidance of Dr. Murali Krishnan K. and Dr. Vineeth Paleri. The work received technical support from Dr. Vineeth Paleri and Dr. Saleena N. .
Please send queries and bug reports to kmuralinitc@gmail.com
SILCNITC by Dr. Murali Krishnan K, Department of Computer Science and Engineering, National Institute of Technology, Calicut is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.
Based on a work at https://github.com/silcnitc
Any pedagogical compiler implementation project offered as part of an undergraduate junior level compiler design course needs to satisfy two fundamental requirements:
The student must be given as much depth and detail as possible about the central concepts. That is, the project must be sufficiently non-trivial to be instructive.
The quantity of work involved must not exceed what a student is able to complete in about four months, taking also into consideration the fact that she/he would be crediting several other courses concurrently. Thus, the project must be sufficiently simple to be do-able.
The problem before the teacher is to decide on how much compromise on (1) must be done in favour of (2). The present project is our stance in this matter. We expain our choices here.
There are two aspects associated with the design and implementation of each major functional unit of a compiler. – 1) A Policy and 2) An implementation Mechanism. As an illustration, consider dynamic memory allocation. Fixed size allocation is a policy. The most common implementation mechanism is to have a run time library that manages allocation from the the heap. As another example, consider passing of parameters to functions. Call by value/call by reference are a policies. Passing values/addresses through a run time stack is the standard implementation mechanism. Yet another example, a language may describe a dynamic method binding policy for supporting subtype polymorphism in single inheritence hierarchy. Virtual function table mechanism is the most common way to implement the policy. Of course, each of the above policies and mechanisms need more detailed and concrete specification. Detailed descriptions of the policies and mechanisms associated with various functions of a compiler are given in the project documentation.
The pedagogical strategy is to specify a programming language that has a very simple policy associated with functional unit of the compiler. This allows the student to implement the policy easily, once the implementation mechanism is understood. For instance, fixed-size allocation policy is specified for dynamic memory allocation. We provide detailed tutorials for various implementation mechanisms necessary to implement the policies associated with each such functional unit of the compiler. This helps the student to learn the implementation mechanisms quickly. Once the student completes the implementation one simple policy that uses a particular mechanism, she will be in a position to visualize the implementation of more sophisticated policies associated with a particular functionality that use similar mechanisms without actually going through an implementation project.
The project is designed to be done concurrently with a theory course in Compiler Design, typically offered during the third year of an undergraduate CS curriculum. It by no means is a replacement to the theory course, but is only designed to suppliment it. The project will help in solidifying the student's grasp of compiler design theory - about how the components of a compiler can be assembled together to form the whole. The student will experience the end-to-end process of translation from a high level language source to a target executable. The road-map is designed in such a way that as far as practicable, only one new concept is introduced at a time.
It is our responsiblity to explicitly state some central concepts that the project fails to teach. Here are some key omissions:
The machine architecture, virtual memory model (and the the target ABI in general) are unrealisitically simple and custom made. Consequently it is easy to generate code for the target platfform, but the platform is far from any real system. To illustrate the level of oversimplification, a memory word of the target machine is assumed to be capable of storing an arbitrary interger or a string. Floating point handling is ommitted. The executable file format is extremely simple to understand, but too restrictive for real use. (There are simplifications in the source language specification as well, but those are less dramatic.)
The project is front-end intensive, but has a thin back-end. Code, register or memory optimizations are not attempted. The focus here is to get working target code generated as easily as possible. The roadmap asks the students to directly traverse an intermediete abstract syntax tree representation of the program and generate assembly language code. This is followed by a linking phase to resolve labels in the target code. Improving the back-end code generation process would require data flow analysis (at least liveliness analysis) which is better done with the support of tools like LLVM. Going into these directions would make the project too heavy for one semester. Typically, a second course in compiler design takes up these topics anyway.
Focus has not been placed on efficient data structuring or following software engineering practices religiously. The road-map suggests a simple implementation that can be built incrementally.
The project is designed to help the student to gain knowledge, appreciation and insight into the working of compilers, but does not try to train the student in professional compiler writing. This particular pedagogical choice has been taken to spare the student from the technicalities of machine architecture, executable/object formats and the complexities of the ABIs of real systems – something that in our experience seems to drive a lot of students away from systems projects. Our hope is that once the basic material is assimilated, the student will be more confident to get involved with these details in professional life.
Feedback data collected from students who credited the course is summarized here.
This project is the second one in a suite of two student learning projects designed to tutor undergraduate CS juniors. The first one in the suite is an OS development project (exposnitc.github.io), which asks the student to implement a simple multi-tasking operating system on the same machine architecture used in the present project. The target code of the compiler implemented in the present project is designed to be executable by the OS implemented in the first project. Our hope is that by going through the projects, the student will gain a clear conceptual understanding of how the two central software systems – the OS and the compiler - work together in a computer system.