Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CASM Examples

This chapter provides practical examples of CASM programs, from simple to complex.

Example 1: Hello World

The simplest CASM program:

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": [],
      "body": [
        {"op": "push_str", "value": "Hello, World!"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Execution trace:

1. push_str "Hello, World!"  → Stack: ["Hello, World!"]
2. cap_call io.print 1       → Prints "Hello, World!", Stack: []
3. ret                       → Returns from main

Example 2: Variables and Arithmetic

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["x", "y", "sum"],
      "body": [
        {"op": "push_int", "value": 10},
        {"op": "store", "name": "x"},
        
        {"op": "push_int", "value": 32},
        {"op": "store", "name": "y"},
        
        {"op": "load", "name": "x"},
        {"op": "load", "name": "y"},
        {"op": "add"},
        {"op": "store", "name": "sum"},
        
        {"op": "push_str", "value": "The sum is: "},
        {"op": "load", "name": "sum"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output: The sum is: 42

Example 3: Conditional (If/Else)

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["age"],
      "body": [
        {"op": "push_int", "value": 18},
        {"op": "store", "name": "age"},
        
        {"op": "load", "name": "age"},
        {"op": "push_int", "value": 18},
        {"op": "ge"},
        {"op": "jmp_if_not", "target": 9},
        
        {"op": "push_str", "value": "You are an adult"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        {"op": "jmp", "target": 11},
        
        {"op": "push_str", "value": "You are a minor"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Control flow:

if age >= 18:
    print("You are an adult")
else:
    print("You are a minor")

Example 4: While Loop

Count from 1 to 5:

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["i"],
      "body": [
        {"op": "push_int", "value": 1},
        {"op": "store", "name": "i"},
        
        {"op": "load", "name": "i"},
        {"op": "push_int", "value": 5},
        {"op": "le"},
        {"op": "jmp_if_not", "target": 14},
        
        {"op": "load", "name": "i"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "load", "name": "i"},
        {"op": "push_int", "value": 1},
        {"op": "add"},
        {"op": "store", "name": "i"},
        
        {"op": "jmp", "target": 2},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output:

1
2
3
4
5

Example 5: Function Calls

Factorial function:

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["result"],
      "body": [
        {"op": "push_int", "value": 5},
        {"op": "call", "function": "factorial"},
        {"op": "store", "name": "result"},
        
        {"op": "push_str", "value": "5! = "},
        {"op": "load", "name": "result"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    },
    "factorial": {
      "params": ["n"],
      "locals": ["temp"],
      "body": [
        {"op": "load", "name": "n"},
        {"op": "push_int", "value": 1},
        {"op": "le"},
        {"op": "jmp_if_not", "target": 5},
        
        {"op": "push_int", "value": 1},
        {"op": "ret"},
        
        {"op": "load", "name": "n"},
        {"op": "push_int", "value": 1},
        {"op": "sub"},
        {"op": "call", "function": "factorial"},
        {"op": "store", "name": "temp"},
        
        {"op": "load", "name": "n"},
        {"op": "load", "name": "temp"},
        {"op": "mul"},
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output: 5! = 120

Example 6: Arrays

Working with arrays:

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["arr", "len", "i"],
      "body": [
        {"op": "push_int", "value": 10},
        {"op": "push_int", "value": 20},
        {"op": "push_int", "value": 30},
        {"op": "new_array", "size": 3},
        {"op": "store", "name": "arr"},
        
        {"op": "load", "name": "arr"},
        {"op": "arr_len"},
        {"op": "store", "name": "len"},
        
        {"op": "push_str", "value": "Array length: "},
        {"op": "load", "name": "len"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "load", "name": "arr"},
        {"op": "push_int", "value": 1},
        {"op": "arr_get"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output:

Array length: 3
20

Example 7: Objects and Structs

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["point"],
      "body": [
        {"op": "new_struct", "name": "Point"},
        {"op": "store", "name": "point"},
        
        {"op": "load", "name": "point"},
        {"op": "push_int", "value": 10},
        {"op": "set_field", "name": "x"},
        {"op": "store", "name": "point"},
        
        {"op": "load", "name": "point"},
        {"op": "push_int", "value": 20},
        {"op": "set_field", "name": "y"},
        {"op": "store", "name": "point"},
        
        {"op": "load", "name": "point"},
        {"op": "get_field", "name": "x"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output: 10

Example 8: File I/O

Reading and writing files:

{
  "version": "0.1",
  "functions": {
    "main": {
      "params": [],
      "locals": ["content"],
      "body": [
        {"op": "push_str", "value": "data.txt"},
        {"op": "push_str", "value": "Hello from CASM!"},
        {"op": "cap_call", "name": "fs.write", "argc": 2},
        
        {"op": "push_str", "value": "File written successfully"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "push_str", "value": "data.txt"},
        {"op": "cap_call", "name": "fs.read", "argc": 1},
        {"op": "store", "name": "content"},
        
        {"op": "push_str", "value": "File content: "},
        {"op": "load", "name": "content"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print", "fs.read", "fs.write"]
  }
}

Example 9: Error Handling

Using metadata for error reporting:

{
  "version": "0.1",
  "lang": "python",
  "functions": {
    "main": {
      "params": [],
      "locals": ["x", "y"],
      "body": [
        {
          "op": "push_int",
          "value": 10,
          "lang": "python",
          "meta": {"file": "script.py", "line": 1, "column": 5}
        },
        {
          "op": "store",
          "name": "x",
          "lang": "python",
          "meta": {"file": "script.py", "line": 1}
        },
        {
          "op": "push_int",
          "value": 0,
          "lang": "python",
          "meta": {"file": "script.py", "line": 2, "column": 5}
        },
        {
          "op": "store",
          "name": "y",
          "lang": "python",
          "meta": {"file": "script.py", "line": 2}
        },
        {
          "op": "load",
          "name": "x",
          "lang": "python",
          "meta": {"file": "script.py", "line": 3, "column": 8}
        },
        {
          "op": "load",
          "name": "y",
          "lang": "python",
          "meta": {"file": "script.py", "line": 3, "column": 12}
        },
        {
          "op": "div",
          "lang": "python",
          "meta": {"file": "script.py", "line": 3, "column": 10}
        },
        {
          "op": "ret",
          "lang": "python",
          "meta": {"file": "script.py", "line": 3}
        }
      ]
    }
  }
}

Error output:

Error at script.py:3:10
  |
3 | result = x / y
  |          ^^^^^
  | Division by zero

Example 10: Complete Program

A complete program with multiple functions and capabilities:

{
  "version": "0.1",
  "lang": "crush",
  "functions": {
    "main": {
      "params": [],
      "locals": ["numbers", "sum", "avg"],
      "body": [
        {"op": "push_int", "value": 10},
        {"op": "push_int", "value": 20},
        {"op": "push_int", "value": 30},
        {"op": "push_int", "value": 40},
        {"op": "push_int", "value": 50},
        {"op": "new_array", "size": 5},
        {"op": "store", "name": "numbers"},
        
        {"op": "load", "name": "numbers"},
        {"op": "call", "function": "sum_array"},
        {"op": "store", "name": "sum"},
        
        {"op": "load", "name": "sum"},
        {"op": "push_int", "value": 5},
        {"op": "div"},
        {"op": "store", "name": "avg"},
        
        {"op": "push_str", "value": "Sum: "},
        {"op": "load", "name": "sum"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "push_str", "value": "Average: "},
        {"op": "load", "name": "avg"},
        {"op": "add"},
        {"op": "cap_call", "name": "io.print", "argc": 1},
        
        {"op": "ret"}
      ]
    },
    "sum_array": {
      "params": ["arr"],
      "locals": ["total", "i", "len"],
      "body": [
        {"op": "push_int", "value": 0},
        {"op": "store", "name": "total"},
        
        {"op": "push_int", "value": 0},
        {"op": "store", "name": "i"},
        
        {"op": "load", "name": "arr"},
        {"op": "arr_len"},
        {"op": "store", "name": "len"},
        
        {"op": "load", "name": "i"},
        {"op": "load", "name": "len"},
        {"op": "lt"},
        {"op": "jmp_if_not", "target": 23},
        
        {"op": "load", "name": "total"},
        {"op": "load", "name": "arr"},
        {"op": "load", "name": "i"},
        {"op": "arr_get"},
        {"op": "add"},
        {"op": "store", "name": "total"},
        
        {"op": "load", "name": "i"},
        {"op": "push_int", "value": 1},
        {"op": "add"},
        {"op": "store", "name": "i"},
        
        {"op": "jmp", "target": 9},
        
        {"op": "load", "name": "total"},
        {"op": "ret"}
      ]
    }
  },
  "manifest": {
    "permissions": ["io.print"]
  }
}

Output:

Sum: 150
Average: 30

Tips for Writing CASM

1. Use Comments in JSON

While CASM itself doesn’t support comments, you can add them in your JSON during development:

{
  "body": [
    {"op": "push_int", "value": 42},
    {"_comment": "Print the value"},
    {"op": "cap_call", "name": "io.print", "argc": 1}
  ]
}

(The VM will ignore unknown fields like _comment)

2. Label Jump Targets

Keep track of instruction indices:

{
  "body": [
    /* 0 */ {"op": "load", "name": "x"},
    /* 1 */ {"op": "push_int", "value": 0},
    /* 2 */ {"op": "gt"},
    /* 3 */ {"op": "jmp_if_not", "target": 6},
    /* 4 */ {"op": "push_str", "value": "Positive"},
    /* 5 */ {"op": "jmp", "target": 7},
    /* 6 */ {"op": "push_str", "value": "Non-positive"},
    /* 7 */ {"op": "cap_call", "name": "io.print", "argc": 1}
  ]
}

3. Always Include Metadata

{
  "op": "add",
  "lang": "crush",
  "meta": {
    "file": "program.crush",
    "line": 10,
    "column": 15
  }
}

4. Validate Your CASM

crush validate program.casm

Next Steps