This question evaluates implementation skills in parsing and evaluating a small arithmetic DSL, covering variable assignment parsing, symbol resolution, and evaluation order; it falls under the Coding & Algorithms category and emphasizes practical application and engineering of a correct evaluator rather than abstract theory.
You are given a small DSL (domain-specific language) consisting of variable assignments, one per line. Each line has the form:
<identifier> = <expression>
<identifier>
is a variable name:
[a-zA-Z_][a-zA-Z0-9_]*
.
<expression>
is a sum or difference of
integer literals
and
variable references
.
+
and
-
only.
=
, around operators, before/after identifiers, etc.
All variables are of integer type. A variable may depend on other variables which might be defined before or after it in the input. The dependency graph may contain chains (e.g. a depends on b, which depends on c, …), and you must resolve all such dependencies.
Implement a function with the following behavior (pseudo-signature):
evaluate(program: string) -> Map<string, int>
program
is a multi-line string; each non-empty line is one assignment.
foo = bar + 5
bar = 2
{ "bar": 2, "foo": 7 }
foo = bar + 1
bar = baz + 1
baz = 3
{ "baz": 3, "bar": 4, "foo": 5 }
foo=bar+5-baz
foo = bar + 5 - baz
foo = bar + 5 - baz
"bar "
) must be trimmed so that variable lookup works correctly.
foo = bar + 1
bar = foo + 1
foo
nor
bar
can be meaningfully evaluated.
cyclic dependency
error).
ok = 1
bad = missing + 1
N
variables and up to
M
total tokens across all expressions, where
N, M
can be large.
evaluate(program: string)
according to the above rules.