Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CS II: Data Structures & Classes in C++

Five from-scratch C++ classes I wrote for Kent State CS23001, each with its own test suite.

C++ License Kent State CI

Overview

This is the coursework I built for Computer Science II (CS23001) at Kent State, Spring 2022. The theme of the course was writing the data structures yourself instead of reaching for the standard library, so every project here is a hand-rolled class plus a set of unit tests that exercise it. The five projects move from a single value type (an arbitrary-precision integer) up to a tree that parses XML and rewrites C++ source.

Projects

BigInt

An arbitrary-precision integer that stores each decimal digit in a fixed int[500] array, least-significant digit first. I overloaded +, *, ==, and the subscript operator, and wrote stream <</>> so a bigint reads from a file and prints across 80-character lines. Multiplication builds on two helpers I wrote, timesDigit and times10, the same way you would multiply on paper. See the BigInt wiki page.

Custom String

A dynamic string class backed by a raw char* that I grow by hand. It does copy construction, a constant-time swap, copy-and-swap assignment, concatenation with +=, lexicographic <, substring, and both find-char and find-string. There is also a logview application that uses the String class to parse Apache-style access logs and report bytes or hosts. See the Custom String wiki page.

Infix→Postfix Assembler

A converter that turns a fully parenthesized infix expression into postfix using a custom linked-list stack<T>, then walks the postfix form to emit mock assembly (AD, SB, MU, DV) with a temporary register per operation. The stack is a templated class with its own copy semantics, and it reuses the String class from the previous project. See the Assembler wiki page.

AST Profiler

An srcML/AST pair that reads the srcML XML form of a C++ file, builds an abstract syntax tree out of category, token, and whitespace nodes, then rewrites the tree to inject profiling counters into every function and statement. The output is an instrumented p-*.cpp file that counts how often each line and function runs. See the AST Profiler wiki page.

Object Construction

A small lab where I traced constructor, copy-constructor, and destructor calls by printing from each one, plus a companion program that shows what happens when you write past the end of a heap array with no bounds checking. See the Object Construction wiki page.

Tech Stack

  • C++11 (the course Makefiles target a newer standard with clang++; the code itself builds clean under g++ -std=c++11)
  • GNU Make, one Makefile per project
  • File-per-test unit testing with <cassert>, no external framework

Architecture

graph TD
    Root[CS II coursework]
    Root --> BI[BigInt]
    Root --> ST[Custom String]
    Root --> AS[Assembler]
    Root --> PR[AST Profiler]
    Root --> OC[Object Construction]

    BI --> BIc["bigint class<br/>digit-array storage"]
    BI --> BIt["test_*.cpp suite"]

    ST --> STc["String class<br/>raw char* + capacity"]
    ST --> STt["test_*.cpp suite"]
    ST --> STa["logview application"]

    AS --> ASc["stack&lt;T&gt; template"]
    AS --> ASt["test_*.cpp suite"]
    AS --> ASa["postfix + assembler"]
    ASc -. reuses .-> STc

    PR --> PRc["srcML / AST classes"]
    PR --> PRa["profile runtime"]

    OC --> OCc["cat class + bounds demo"]
Loading

Each box under a project is either the class I wrote, the test suite that checks it, or an application built on top. The dashed line shows that the assembler's stack stores String values from the String project.

Getting Started

Prerequisites

  • g++ (or clang++), a C++11-capable compiler
  • make

Build and run a project

Each project has its own Makefile. Pick a project, build it, run it:

cd bigint
make tests        # build and run the full assertion suite
make add          # build the addition demo (reads data1-1.txt)
make multiply     # build the multiplication demo (reads data1-2.txt)

The other projects follow the same shape:

cd string && make tests        # String unit tests
cd string && make logview      # the log-parsing application

cd assembler && make tests     # stack unit tests
cd assembler && make assembler # infix -> postfix -> assembly

cd profiler && make profiler   # the source-instrumentation tool

The object_construction lab has no Makefile. Compile it directly:

cd object_construction
g++ -std=c++11 object_construction.cpp object_test.cpp -o object_test && ./object_test
g++ -std=c++11 array_bounds_check.cpp -o bounds_check && ./bounds_check

Project Structure

cs2-projects/
├── bigint/                 arbitrary-precision integer
│   ├── bigint.hpp / .cpp   the class
│   ├── add.cpp             addition demo
│   ├── multiply.cpp        multiplication demo
│   ├── test_*.cpp          assertion tests
│   └── Makefile
├── string/                 dynamic string class
│   ├── string.hpp / .cpp   the class
│   ├── logview.cpp         log-parsing application
│   ├── logentry.hpp / .cpp log record + parsing
│   ├── test_*.cpp          assertion tests
│   └── Makefile
├── assembler/              infix -> postfix -> assembly
│   ├── stack.hpp           templated linked-list stack
│   ├── utilities.hpp / .cpp conversion + assembly emit
│   ├── postfix.cpp         infix -> postfix driver
│   ├── assembler.cpp       full pipeline driver
│   ├── test_*.cpp          stack assertion tests
│   └── Makefile
├── profiler/               srcML AST source instrumenter
│   ├── ASTree.hpp / .cpp   srcML + AST classes
│   ├── profile.hpp / .cpp  runtime counter
│   ├── main.cpp            driver
│   └── Makefile
├── object_construction/    constructor/destructor lab
│   ├── object_construction.hpp / .cpp
│   ├── object_test.cpp
│   └── array_bounds_check.cpp
└── wiki/                   per-project documentation

Testing

The course used a file-per-test convention and I kept it. Every test_*.cpp is a standalone program with its own main. It sets up a fixture, calls the method under test, and checks the result with assert. If every assertion holds the program prints a "passed" line and exits 0; the first failed assertion aborts with a non-zero exit. The Makefile has a pattern rule (test_%) that compiles each test against the class object file, and a tests target that builds them all and runs them in sequence. A passing make tests means every assertion in the suite held.

There is no Catch2 or GoogleTest here. The whole harness is <cassert> and the Makefile, which is the point of the exercise.

Roadmap

  • BigInt has no subtraction or division, and no sign handling, so it is positive-only. Adding those would round it out.
  • The custom String reallocates on every +=, which is fine for the log files here but quadratic for heavy concatenation. A capacity-doubling growth policy would fix that.
  • The assembler assumes fully parenthesized input. A real shunting-yard pass with operator precedence would let it accept plain expressions.
  • The object_construction lab could use a Makefile so it builds the same way as the others.

Author & Acknowledgments

Brandon Robare.

This is academic coursework for Kent State University, CS23001 (Computer Science II), Spring 2022. Several headers and the srcML reader were provided by the instructor, Dr. J. Maletic, as starting points; the class implementations, test suites, and applications are my work. Provided files are marked in their own header comments.

License

MIT. See LICENSE and the License page in the Wiki.

About

Data structures built from scratch in C++ (Kent State CS II): an arbitrary-precision BigInt, a custom String class with a log parser, an infix-to-postfix assembler, and a source-code AST profiler, each with a unit-test suite.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages