> ## Documentation Index
> Fetch the complete documentation index at: https://docs.atopile.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 1. `ato` Language

> `ato` is a domain specific language (DSL) for describing electronic circuit boards. It's heavily inspired by, and attempts to follow the syntax of Python 🐍 for consistency and familiarity.

## Basic types

The most basic types in `ato` are a `module` and an `interface`.

An `Electrical` is a special built-in type of `interface` that represents a single [electrical](https://github.com/atopile/atopile/blob/main/src/faebryk/library/Electrical.py#L7) interface.

A `component` is a subclass of a `module` that expects to represent a single physical component.

You can also define your own types, in a similar way to defining a `class` in Python.
Like classes in most modern languages, you can subclass and inherit from blocks.

```python theme={null}
module SomeModule:
    some_signal = new ElectricSignal
    gnd = new Electrical
    some_signal.reference.lv ~ gnd
    some_variable = "some value"

module SubclassedModule from SomeModule:
    # inherits all the signals and variables from SomeModule
    # we don't need to declare the signals again,
    # but we will replace the value of some_variable
    some_variable = "some other value"

module Test:
    gnd = new Electrical
    # creates an instance of the SubclassedModule
    subclassed_module = new SubclassedModule
    # connects the some_signal of the SubclassedModule to the gnd of Test
    subclassed_module.gnd ~ gnd
```

<Note>
  You can subclass a `module` as a `component`, but not the other way around. A component is expected to represent a specific component.
</Note>

## Configuring blocks

Configuration of a `module` or `interface` is done by assigning to its attributes.

```ato theme={null}
some_instance.value = 100ohm +/- 10%
```

Unlike Python, you don't need to state `self.` Instead, any assignments you make within the scope of a block, are automatically assigned to the block.

Built-in attributes influence the behavior of the compiler with respect to the block.

Setting the `package` attribute, for example, makes the compiler select only components with the specified package to use in that component's slot.

## Connecting it up

Any `interface` can connect to any other interface of the same type using the `~` operator.

```ato theme={null}
some_signal ~ another
```

## Units and tolerances, assertions and maths

Remember how NASA slung a rocket straight into Mars because of a metric/imperial error?

Let's not do that again.

### Units

Resistors' resistances must be a resistance; whether `1.23Ω` (option+Z on macOS), `1.23ohm`, `4.56Kohm`, `7.89Mohm` or similar.

Any attribute of any block may have a unit attached, written (without a space) after any number.

Unsurprisingly, a capacitor's capacitance needs to be a capacitance (for example, `23.4uF`); other limits are in volts, amperes, degrees, and so on.

Add units.

### Tolerances

Another unfamiliar first-class language feature when dealing with the physical world is the ability (and generally specification)
to spec tolerances for attributes.

You could try to find a `10kΩ` resistor, but it probably won't exist - it'll likely be at least `10kΩ +/- 0.1%` (which you can write!).

Tolerances can be written in the forms of:

* `1V to 2V`
* `3uF +/- 1uF`
* `4Kohm +/- 1%`

These are hopefully sufficiently intuitive to not warrant further explanation 🤞

### Units and Tolerances

With Units and Tolerances together, physical attributes can be defined.

Several legal ways exist to combine them.

* `3V to 3.6V` perhaps for a supply rail
* `3V +/- 10mV` maybe for a reference
* `4.7uF +/- 20%` for a generic cap
* even `25lb +/- 200g` 🤣

### Sweet, so now that all these values are around the place, what can be done with them?

✨ **Maths** ✨

atopile does two things for you with these values:

1. Check that assertions about their relationships to one another are true
2. Solve systems of constraints based on these relationships to find component values

This maths is all done including the units and tolerances, so you can be absolutely sure everything always works.

Use the `assert` keyword to apply constraints on the values of attributes to one another.

Supported operators are currently `<`, `>` and `within` (all are inclusive of the bounds).

```atopile theme={null}
a = 1 ± 0.1
b = 2 ± 0.2
c: resistance  # variable declaration without assignment

assert a < b  # always true before 0.9 and 1.1 (the bounds of a) are both lower than the bounds of b (1.8 and 2.2)
assert a > b  # always false --> Yields a failure at compile time
assert c within 1Kohm to 10Kohm  # first solved for, then the solution is independently checked at the end of the build
```

Not sure about you, but this author (Matt) is not fond of working too hard.
Perhaps you've got a better method, but generally, when trying to find resistor values for something as simple as a voltage divider, one is guessed that seems approximately right, then the other is calculated—giving something that doesn't exist—before finally checking through a few other nearby options until finding a pair that works.

This is fine and dandy as long as you only care about the ratio of a voltage divider, but as soon as the check for what that does for the regulator's output voltage is needed? Ugh, fine! What about the extremes of the tolerances on those resistors? Fine, it can be done once—but if someone goes to tweak those values for whatever reason, the author is unlikely to be pleased.

Therefore, let atopile do it!

atopile automatically solves systems of constraints for you with free variables, and checks that the values of attributes are within their tolerances.

## Specialization

The `->` operator will specialize a module from its existing instance to an instance of the type on the right-hand side.

```ato theme={null}
some_instance -> AnotherModuleType
```

This is useful for configuring a topology specified earlier.

## Imports

You can import assets by specifying what you want to import and where you want to import it from using the following syntax within your `.ato` files:

`from "where.ato" import What, Why, Wow`

Notes on that statement:

* Add quotes on the "where.ato"—it's a string.
* `What`, `Why`, and `Wow` are capitalized because they are in the source file. It has to match precisely—it's a type, and types should be capitalized, though this isn't enforced, and you can import things other than types from other files.

The import statements are relative to the current project (the root of which is where your `ato.yaml` is), or within the standard library (`.ato/modules/`)

<Warning>
  You'll likely see import statements in the form of `import XYZ from "abc.ato"`. This is a legacy syntax and will be removed in the future. Use the new syntax.

  It also doesn't support importing multiple things on the same line.
</Warning>
