01_primitives

Primitive Types

Primitive Types and Operations

Purpose

The ARES standard library defines the fundamental set of types and operations that form the core of the language. These are the basic building blocks, like numbers, text, and simple lists. Unlike complex algorithms, these primitives are directly connected to the native features of your chosen target language (C++, Python, or TypeScript). This allows ARES to remain lightweight while still providing a safe and powerful way to handle data.

Why it exists

Every program needs to store and move information. You need to know if a piece of data is a whole number, a decimal, or a line of text. The standard library exists to provide a consistent way to handle these common tasks across all languages. It ensures that when you say "read a list of numbers" in ARES, the system knows exactly how to do that in C++ or Python without you needing to learn the specific syntax for each one. It provides a simple and universal "grammar" for data.

How it works

The system uses specific rules to map ARES types to the target language.

  1. Scalar mapping. Simple values are mapped to the most efficient 64-bit equivalents. For example, an "int" in ARES is mapped to a long long in C++ to prevent errors with large numbers.
  2. Handling containers. ARES understands complex groups like "a list of lists" or "a map of text to numbers." During compilation, it identifies these structures and builds the correct native versions (like std::vector or a Python dict).
  3. Automatic Input and Output. Commands like read and print are designed for common tasks. They automatically handle space-separated input or standard text formatting so you don't have to write custom loops for every data read.
  4. Strict tracking. The compiler keeps track of every variable's type. If you try to perform a math operation on a piece of text, the system will catch that mistake before the program ever runs.

Intuition

Think of primitive types like the basic vocabulary of a language. You have nouns (the data types), verbs (the operations like read or print), and simple adjectives (the boolean values). Just like you need a basic vocabulary before you can write a complex novel, you need these primitives before you can build a complex algorithm. They are the essential tools you use to describe your logic to the computer.

Implementation details

The logic for handling these types is located in src/semantics/analyzer.ts.

  • Numbers: Standard math symbols like +, -, *, and / are mapped directly to their equivalents in every language.
  • Strings: Text can be wrapped in either single or double quotes.

Complexity

Operating on a single piece of data happens almost instantly (constant time). Reading a whole list of data takes an amount of time that grows linearly with the size of the list.

Trace example

This is what happens when you read a vector of integers read nums as vector<int>:

  1. Preparation: The system identifies that you want to store several numbers.
  2. Size check: In a C++ target, it first writes code to read the number of items that are coming.
  3. Creation: It creates a std::vector<long long> of that exact size.
  4. Filling: It uses a standard loop to read every individual number from your console and place it into the vector.

Related entities

  • 2_language_reference/03_ast_nodes.md: Explains how these types are stored inside the compiler's memory.
  • 8_registry_approaches/01_cp_core.md: Shows how these basic types are used to build more advanced tools.
ARES