I am quite sure JOVIAL, ESPOL/NEWP, ALGOL and PL/I dialects, Lisp, which predated C in more than a decade have enough abstraction capabilities, even by their state in 1972.
Interlisp initially created in 1970, besides the lists everyone knows, introduced atoms, string, arrays and compound data types, which alongside macros provided the necessary foundation to create abstract data types
> The language which most closely resembles, in form, the language presented here is SIMULA 67. 8
SlMULA class definitions have many similarities with cluster definitions.
Yeah it doesn't, that is why there are enough papers and books how to implement them with incomplete types, and translation units with statics as poor man's replacement for modules.
Again, there is already a well known solution for this problem -- C++
And it's trivial to upgrade to from C
So basically, use EITHER idiomatic C, which means long functions / few internal interfaces, reuse with ABIs not APIs, bespoke data structures, etc.
OR use C++ and ADTs (type safety, abstraction, polymorphism). Or use Rust if you don't need compatibility.
So books like CII are of very limited use, especially not for beginners. They will be fighting with the language and not understanding what it's about.