git @ Cat's Eye Technologies Tamsin / master mains / mini-tamsin.tamsin
master

Tree @master (Download .tar.gz)

mini-tamsin.tamsin @masterraw · history · blame

# Interpreter for "Mini-Tamsin", written in Tamsin.
# (see doc/Mini-Tamsin.markdown.)
# Distributed under a BSD-style license; see LICENSE.

# REQUIRES lib/tamsin_scanner.tamsin
# REQUIRES lib/tamsin_parser.tamsin

main = tamsin_parser:parse → AST & tamsin_scanner:skippable & "/" &
       new_state → S &
       interpret(AST, S, AST).

#
# FIXME there are several rather major shortcomings with this, still!
#

new_state = return state().

#
# interpret(EntireProgram, State, CurrentProgramPart)
# returns a pair(Result, NewState)
#
interpret(P, S, program(L)) =
    tamsin_parser:find_production_global('main', 'main', P) → Main &
    new_state → S &
    interpret(P, S, Main).

interpret(P, S, production(N, list(prodbranch(Fs, Ls, E), nil))) =
    interpret(P, S, E).

interpret(P, S, call(prodref('$', 'return'), list(atom(X), nil))) =
    return pair(X, S).

interpret(P, S, call(prodref('$', 'expect'), list(atom(X), nil))) =
    «X» → R &          # FIXME this isn't going to work if «X» fails, is it.
    return pair(R, S).

interpret(P, S, call(prodref('$', 'print'), list(atom(X), nil))) =
    print X &
    return pair(X, S).

interpret(P, S, call(prodref('', N), A)) =
    interpret(P, S, call(prodref('main', N), A)).

interpret(P, S, call(prodref(M, N), A)) =
    tamsin_parser:find_production_global(M, N, P) → Prod &
    new_state → S2 &
    interpret(P, S2, Prod).

interpret(P, S, or(L, R)) =
    interpret(P, S, L) → pair(Res, S2) &
    (Res & return pair(Res, S2)) | interpret(P, S, R).
    # FIXME what happens to S?  I think this is right though

interpret(P, S, and(L, R)) =
    interpret(P, S, L) → pair(Res, S2) &
    interpret(P, S2, R).

# interpret(P, S, not(X)) = !interpret(P, S, X).

interpret(P, S, while(X)) =
    {interpret(P, S, X) → pair(Res, S2) & set S = S2}.