Example Code
This page provides some samples of C code shown in class.
Connection Between Unix and C
- The Unix echo command, which shows how Unix C code is connected to the operating system.
Tiny Virtual Machine
The tiny machine is a Von Neumann VM that is very simple. The ISA for this machine is also available. The implementation uses the following files:
- machine_main.c, which is the main program.
- machine.h and machine.c, which implement the main functionality of the VM.
- instruction.h and instruction.c, which are an abstract data type for the VM's instructions.
- utilities.h and utilities.c which has some utility functions (including printing error messages.
- The project's Makefile, which describes how to build and test it. Testing uses the .txt files in the tiny-machine directory and expected outputs are in the .out files
- The project's sources.txt file, which tells the Makefile what to compile.
Stack with support for ARs
The stack module shown here has support for activation records (ARs) and static scoping; it is an abstract data type in C, which hides some state by making it static.
- The machine_types.h file, which defines types used in the stack
- The stack.h and stack.c files that define the stack's interface and implementation.
- The utilities.h and utilities.c file that defines some utility functions.
Trees: a motivating example for recursion
The trees example shows how to compute the depth of a binary tree both recrusively and non-recursively, so that one can see how much simpler the recursive solution is. In fact, the non-recursive solution is more difficult, and seems to be easiest to express using two queues.
- The Tdef.h file, which defines a type T for the values of the tree nodes (this is not important).
- The btree.h and btree.c files that define binary trees and their dynamic creation.
- The depth_recursive.cfile that is a recursive algorithm for computing the depth of a binary tree.
- The depth_while.c that is a non-recursive algorithm for computing the depth of a binary tree.
- The depth_test.c that tests implementations of the depth function.
- The Makefile that can be used to build and test the project.
- The utilities.h and utilities.c file that defines some utility functions.
Strings in C
The testre.c function shows that the standard C library's strcmp() function does not do regular expression matching.
Modular C
The decldef.h file shows several declarations that are not definitions in C; there are corresponding definitions in the file decldef.c file.
The non-modular program sayHelloProgram.c is broken into 3 modules in:
- A main module, found in sayHelloMain.c,
- A sayHello module, found in sayHello.h and sayHello.c, and
- A who module, found in who.h and who.c
There is a simple Makefile available that can separately compile these modules and link together a complete program.
The ADT for string sets is a module composed of:
- A header file, string_set.h, and
- An implementation file, string_set.c.
Building ASTs Manually
The directory building_ASTs_manually shows two ways to build abstract syntax trees (ASTs) for PL/0, using the ast module from homework 3.
See the file demo.c for how to build ASTs for some simple statements. There is also a header in demo.h and a main program in demo_main.c, which uses the input file write_x.pl0 in one technique.
The directory also contains several other files needed for the demonstration, including a Makefile.
FLOAT Calculator Compiler
The directory FLOAT calculator is an example compiler for a very simple calculator language called FLOAT. (See float-calculator.zip for a zip file of all the relevant source files in this directory.) It shows how to do lexical analysis, parsing, construction of ASTs, declaration checking (via a walk over the ASTs), and code generation (also via walking the ASTs). A Makefile that builds the compiler and can run tests is included.
The main function (in the file compiler_main.c)
- calls the parser (the parser module consists of the files: parser.c, parser.h, and parserInternal.h),
- the parser returns an AST for the program,
- if the -u option was used, then the compiler prints a textual version of the AST on standard output by calling the unparser (this module consists of the files: unparser.h and unparser.c),
- then the compiler initializes the symbol table (in symtab.h and symtab.c), which in turn initializes the first scope (using the scope module found in the files scope.h and scope.c)
- the symbol table is used to perform checking for duplicate declarations of identifiers and undeclared identifiers using the scope_check module (files scope_check.h and scope_check.c), as well as adding id_use structures to the ASTs for each identififer use (these contain id_attr structures, which are used in code generation).
- Finally, code generation is done in the gen_code module (files gen_code.h and gen_code.c), and the code (in the VM's input format) is output to standard output.
Error messages are handled in the utilities module (see utilities.h and utilities.c).
The type AST of abstract syntax trees for the FLOAT language are declared in the ast module (see ast.h and ast.c). This uses the file location type from the file_location module (see file_location.h and file_location.c). Information about type attributes of variables uses the type var_type from the type_attrs module (see type_attrs.h and type_attrs.c).
ASTs for identifier uses contain (a pointer to) an id_use structure, from the id_use module (files id_use.h and id_use.c).
Attributes stored in the symbol table and in an id_use structure are defined in the id_attrs module (see id_attrs.h and id_attrs.c). The type id_attrs also uses the types file_location and var_type mentioned above.
Float Stack-based VM
The virtual machine (VM) is a stack-based VM that is used for the FLOAT calculator. It is found in the vm subdirectory of the float calculator directory. A description of the FLOAT VM is provided in a PDF file.
The implementation uses the following files:
- machine_main.c, which is the main program.
- The machine module (files machine.h and machine.c), which implements the main functionality of the VM.
- The machine_types module (files machine_types.h and machine_types.c), which declares the types address and word and implements some utility functions related to those tyeps.
- The stack module (files stack.h and stack.c), which implements the runtime stack and encapsultes the BP and SP pointers.
- The instruction module (files instruction.h and instruction.c), which are an abstract data type for the VM's instructions.
- The utilities module (files utilities.h and utilities.c) which has some utility functions (including printing error messages.
- The project's Makefile, which describes how to build and test it. Testing uses the .vmi files in the float-calculator/vm directory and expected outputs are in the .out files
- The project's sources.txt file, which tells the Makefile what to compile.
Last modified .