works for valid programs, needs testing with invalid programs