DEV Community

Cover image for Buffing A 50 Year Old Programming Language
Alex
Alex

Posted on

Buffing A 50 Year Old Programming Language

Hello, everyone! Today, I'm excited to take you on a journey through the fascinating world of programming languages and compilers. We'll be exploring a new language I'm developing called "Mantle" (or simply "M"). But before we get into the nitty-gritty, let's discuss the architecture of Mantle and what I aim to achieve with it.

The Inspiration Behind Mantle

I've been immersed in programming with C and C++ for a considerable time, primarily working on 3D computer graphics using Vulkan. My initial exploration into programming began with C++, which I grew to love for its high-level constructs and powerful memory management capabilities. However, I often found C++ to be overly complex. I gradually developed a preference for C. C's simplicity, with its minimal abstraction over assembly, provided a clearer understanding of how the hardware operates.

Yet, I frequently found myself torn between C and C++ when starting new projects. Each language has its strengths and weaknesses, and I wanted to create one that blends the best aspects of both. Thus, Mantle was born.

The Design Philosophy of Mantle

Today I will just briefly show you an overview of what I think Mantle can look like.

Organizing Code: Namespaces

One of the challenges in C is the lack of a robust mechanism for code organization, leading to messy codebases. Mantle addresses this by incorporating namespaces from C++, allowing for better code grouping and organization.

Namespaces

Defining Interfaces: Protocols

Mantle introduces the concept of “protocols". Protocols define requirements, such as functions and variables, that must be implemented by adopting types. This brings us to the “prototype” keyword, which acts as a placeholder for types specified when the protocol is adopted. This design encourages composition over inheritance, promoting flexible and modular code.

Protocols

Creating Classes: Blueprints

In Mantle, “blueprints” are akin to classes in other languages. Blueprints support public and private members, constructors, and destructors for managing resources. Unlike C++, Mantle distinguishes between structs and blueprints. Structs are used for grouping related variables, while blueprints facilitate object-oriented programming.

Blueprints

Extending Functionality: Extensions

To extend a blueprint's functionality for specific parts of the code, Mantle uses the “extension” keyword. This allows functions to be associated with a blueprint only within a particular file, providing modular and context-specific extensions.

Extensions

Extensions

Eliminating Redundancy: Generics

Generics are a powerful feature in Mantle, enabling the definition of functions, blueprints, structs, and variables with types specified later. This reduces code repetition and enhances flexibility.

Generics

Powerful Preprocessing: Macros

In Mantle, macros are defined with the “macro” keyword, leveraging generics for powerful code inclusion before compilation. This concept builds on the preprocessor directives of C and C++.

Macros

Core Concepts: Pointers and Optionals

Mantle incorporates pointers and optionals as core language features. If you have ever programmed in Swift or have used the std::optional<T> in C++ you might be quite familiar with this. Optionals represent values that may or may not be present, providing a type-safe way to handle absent values. Pointers, on the other hand, store memory addresses, enabling direct memory manipulation.

Building Mantle: The Lexical Analyzer

With an understanding of Mantle's design, let's dive into building the language, starting with Lexical Analysis, or lexing. Lexing transforms raw source code into tokens, which are the fundamental syntax elements.

Defining Token Types

We'll begin by defining the types of tokens Mantle will recognize:

  • Keywords: Data types, control flow constructs, data structures, and reserved words.
  • Operators: Arithmetic, relational, pointer, bitwise, and assignment operators.
  • Punctuators: Parentheses, curly brackets, square brackets, commas, etc.
  • Identifiers: Names given to variables, functions, and types.
  • End of File: Marks the end of the source file.

These tokens will evolve as the language matures and its functionality is refined.

The Lexing Process

Next, we'll write a lexer that processes a file, identifies tokens, and stores information for error handling, such as the token's position in the source file. Once identified, tokens are categorized and queued for further processing.

Lexing

Testing the Lexer

To test our lexer, we'll hardcode a function that processes tokens and generates assembly code. For example, writing a "return" statement followed by a value, passing this file through our lexer, and generating assembly code will validate our lexer's functionality.

Testing

Here are some more extreme tests.

Testing

Testing

Conclusion

We've successfully laid the groundwork for Mantle and developed a basic lexer. There's much more to explore and build, but I hope you've enjoyed this initial exploration into the process. If you found this interesting, feel free to connect with me and to share any suggestions.

You can find the project on my github. I also made a discord server.

If you have some feedback/suggestions let me know in the comments! Thanks for joining me on this journey, and I'll see you in the next time!

Top comments (5)

Collapse
 
codeawareness profile image
Mark Vasile

This looks interesting, and I applaud your efforts, creating a new programming language is not easy. I would encourage you to look even more outside the box, and dream of new paradigms. Ask questions: what are the most overused or abused features today, and how can I improve the situation? What other ways to program can we come up with, something completely "out there"?

Collapse
 
mantlecore profile image
Alex

Thank you, it means a lot! You also make a very good point. My current goal is to have the foundation of the language laid out before I get into parsing grammar. I will take these questions into account.

Collapse
 
siy profile image
Sergiy Yevtushenko
  • I highly suggest to take a look at parsing expression grammars, especially cpp-peglib and its playground.
  • You might find very useful to take a look at Rust for inspirations. Especially it's worth to notice use of traits for describing behavior of the object, like Copy, Clone, Drop. It looks much cleaner than C++ approach with copy constructor and other related stuff.
  • you might find interesting to take a look at my experiments with design of similar language. Today I'd make some things differently, but have no time for that.

Good luck!

Collapse
 
mantlecore profile image
Alex • Edited

These are fascinating repos, and I'll consider them when I get into parsing. Thank you! I agree, I'm also not a fan of the C++ approach.

Thank you once again, much appreciated!

Collapse
 
gahuber95 profile image
Gary Huber

This is nice! Another c-based minimal language that I have found interesting is Zig.