Module: Aura

Defined in:
lib/aura.rb,
lib/aura/docker.rb,
lib/aura/parser.rb,
lib/aura/vercel.rb,
lib/aura/codegen.rb,
lib/aura/emitter.rb,
lib/aura/version.rb,
lib/aura/analyzer.rb,
lib/aura/diagnostics.rb,
lib/aura/transformer.rb

Defined Under Namespace

Modules: Diagnostics, Docker, Nodes, Vercel Classes: Analyzer, CodeGen, DeployError, Emitter, ParseError, Parser, SemanticError, Transformer

Constant Summary collapse

STARTER_TEMPLATE =

A small, fully-parseable starter app used by ‘aura init` and the “file not found” recovery path in `aura run`. Kept here so the CLI and the test-suite share a single source of truth.

<<~AURA
  environment production do
    device :cpu
    log_level :info
  end

  model greeter neural_network do
    input text
    output greeting "Hello from Aura!"
  end

  route "/hello" get do
    output prediction from greeter.predict(input) format :json
  end

  run web on port: 3000
AURA
VERSION =

Single source of truth for the framework version. Referenced by the gemspec, the CLI banner, and the generated-code header so they can never drift apart again.

"1.3.0"

Class Method Summary collapse

Class Method Details

.build_docker(filename) ⇒ Object

Generate Docker deployment assets for a .aura file (backs ‘aura deploy`).



116
117
118
# File 'lib/aura.rb', line 116

def build_docker(filename)
  Docker.build(filename)
end

.build_vercel(filename) ⇒ Object

Generate Vercel deployment assets for an LLM-only .aura file (backs ‘aura deploy <file> –target vercel`).



122
123
124
# File 'lib/aura.rb', line 122

def build_vercel(filename)
  Vercel.build(filename)
end

.parse(source) ⇒ Object

Parse source into the raw Parslet tree, converting a Parslet failure into a friendly Aura::ParseError with line/column. Returns the raw tree so callers may run the Transformer themselves.



87
88
89
90
91
92
# File 'lib/aura.rb', line 87

def parse(source)
  clean = preprocess(source)
  Parser.new.parse(clean)
rescue Parslet::ParseFailed => e
  raise Diagnostics.from_parslet(e, clean)
end

.preprocess(source) ⇒ Object

Strip ‘#` comments before parsing – both full-line and trailing/inline (e.g. `scheduler :step_lr # note`). A `#` inside a double-quoted string is left intact. Comment text is removed but newlines are preserved, so line numbers stay accurate for diagnostics. Also normalizes the source to UTF-8 (examples may contain emoji, etc.).



57
58
59
60
# File 'lib/aura.rb', line 57

def preprocess(source)
  source.to_s.dup.force_encoding("UTF-8")
        .each_line.map { |line| strip_comment(line) }.join
end

.run_file(filename) ⇒ Object

Transpile and execute a .aura file. Generated code uses classic Sinatra, which boots the server at exit.



111
112
113
# File 'lib/aura.rb', line 111

def run_file(filename)
  eval(transpile(File.read(filename)), TOPLEVEL_BINDING, filename) # rubocop:disable Security/Eval
end

.strip_comment(line) ⇒ Object

Remove a trailing ‘# …` comment from a single line, ignoring any `#` that sits inside a double-quoted string. Backslash escapes are honored so a `"` inside a string does not prematurely end it. A trailing newline (if present) is preserved so downstream line numbers do not shift.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/aura.rb', line 66

def strip_comment(line)
  in_string = false
  escaped   = false
  line.each_char.with_index do |ch, i|
    if escaped
      escaped = false
    elsif ch == "\\"
      escaped = true
    elsif ch == '"'
      in_string = !in_string
    elsif ch == "#" && !in_string
      tail = line.end_with?("\n") ? "\n" : ""
      return line[0...i].rstrip + tail
    end
  end
  line
end

.to_nodes(source) ⇒ Object

Full front-end: parse -> transform -> semantic analysis. Returns the flat list of semantic node hashes.



96
97
98
99
100
101
102
# File 'lib/aura.rb', line 96

def to_nodes(source)
  tree  = parse(source)
  nodes = Transformer.new.apply(tree)
  nodes = nodes.is_a?(Array) ? nodes : [nodes]
  nodes = nodes.flatten.compact.select { |n| n.is_a?(Hash) }
  Analyzer.analyze(nodes)
end

.transpile(source) ⇒ Object

Transpile Aura source to a Ruby program (String).



105
106
107
# File 'lib/aura.rb', line 105

def transpile(source)
  CodeGen.generate(to_nodes(source))
end