# Ofort interpreter for Fortran

**URL:** <https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879>\
**Category:** Announcements\
**Created:** [April 30, 2026, 4:55am UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879 "2026-04-30T04:55:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [April 30, 2026, 4:55am UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/1 "2026-04-30T04:55:47Z")

</div>

I forked the new [CodeBench](https://github.com/yu314-coder/CodeBench) project (compiler tools for Mac and iPad), extracted just the Fortran interpreter, and increased its coverage of Fortran using Codex, now covering much of Fortran 95 and parts of later standards. The interpreter is written in C and can be compiled with gcc or clang. It’s called ofort because in the original project it was named the OfflinAi Fortran Interpreter. It can be run interactively or with `ofort foo.f90` but does not produce stand-alone executables. There is much of Fortran remaining to be covered, but I think it is already interesting to play with.

> **[GitHub - Beliavsky/ofort: Small C-based interpreter for a practical subset...](https://github.com/Beliavsky/ofort)**
>
> Small C-based interpreter for a practical subset of Fortran 90/95/2003, with a command-line interface

A sample session is

```auto
c:\c\public_domain\github\ofort>ofort
Enter Fortran source.
Commands: . runs, .run [n] [-- args] repeats, .time [n] [-- args] times, .runq [n] [-- args] runs and quits, .quit quits, .clear clears, .del n[:m] deletes lines, .ins n text inserts, .rep n text replaces, .rename old new renames, .list lists, .decl lists declarations, .vars [names] lists values, .info [names] lists details, .shapes [names] lists array shapes, .sizes [names] lists array sizes, .stats [names] lists array stats, .load file loads, .load-run file loads/runs.

ofort> integer, parameter :: n = 10**7
ofort> integer, parameter :: dp = kind(1.0d0)
ofort> real(kind=dp) :: x(n)
ofort> call random_number(x)
ofort> print*,sum(x)/size(x)
ofort> .time 5
0.5000781
0.5001794
0.4998747
0.4998919
0.4998335

   total avg sd min max
6.210490 1.242098 0.070298 1.176757 1.361660 s

ofort> .shapes
x: 10000000
ofort> q
Saved main.f90

```

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [April 30, 2026, 2:30pm UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/2 "2026-04-30T14:30:18Z")

</div>

> [@Beliavsky](#):
>
> ```auto
> total avg sd min max
> 6.210490 1.242098 0.070298 1.176757 1.361660 s
> 
> ```

Does the above take 1s to execute?

In LFortran everything is instant:

```auto
$ lfortran
Interactive Fortran. Experimental prototype, not ready for end users.
LFortran version: 0.63.0-186-gf083bf364
  * Use Ctrl-D to exit
  * Use Enter to submit
  * Use Alt-Enter or Ctrl-N to make a new line
    - Editing (Keys: Left, Right, Home, End, Backspace, Delete)
    - History (Keys: Up, Down)
>>> integer, parameter :: n = 10**7 1,32 ]
>>> integer, parameter :: dp = kind(1.0d0) 1,39 ]
>>> real(kind=dp) :: x(n) 1,22 ]
>>> call random_number(x) 1,22 ]
>>> print*,sum(x)/size(x) 1,22 ]
0.50001864952994668

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [April 30, 2026, 3:34pm UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/3 "2026-04-30T15:34:33Z")

</div>

Yes, more than a second. It’s an interpreter, and I have not tried to optimize speed. For smaller problems the overall time taken by ofort can be lower than the time taken to compile and run with gfortran. For the program

```fortran
integer, parameter :: n = 10**4
integer, parameter :: dp = kind(1.0d0)
real(kind=dp) :: x(n)
call random_number(x)
print*,sum(x)/size(x)
end

```

on my PC the run time is 0.1s with ofort and the compile time is about 0.3s with gfortran or ifx. A compilable source file is created at the end of an interactive session.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 7, 2026, 3:44am UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/4 "2026-05-07T03:44:49Z")

</div>

Ofort now has a --fast option, so `.times 5` for the program above gives

`total avg sd min max `

`0.222714 0.044543 0.002006 0.042517 0.047595 s`

and it is faster than gfortran and ifx for some [microbenchmarks](https://github.com/Beliavsky/ofort/blob/main/benchmark_results.txt), with the codes [here](https://github.com/Beliavsky/ofort/tree/main/benchmarks). Without a compilation step it gives instant results for moderate size problems. The coverage of Fortran has improved using the [Fujitsu test suite](https://github.com/fujitsu/compiler-test-suite). Ofort does not support coarrays or full runtime polymorphism, including `select type`, but it does support type-bound procedures. There is a simple cross-platform (I hope, only tested on Windows) GUI using Python that runs ofort and also gfortran, ifx, and LFortran. It only handles a single source file.

Codex 5.5 quickly fixes bugs, which I hope people will submit.

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [May 7, 2026, 5:04am UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/5 "2026-05-07T05:04:17Z")

</div>

So you can rename it “sofort” now 😅.

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [May 7, 2026, 7:01am UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/6 "2026-05-07T07:01:05Z")

</div>

Do you plan to provide a Fortran binding? Now Ofort can be used as a repl but if you statically link it to a Fortran code one could create an ‘eval’ function or some kind of lambdas.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 7, 2026, 12:03pm UTC](https://fortran-lang.discourse.group/t/ofort-interpreter-for-fortran/10879/7 "2026-05-07T12:03:00Z")

</div>

Good idea – added a Fortran binding, as detailed in the README. One can now a run a program

```fortran
program demo_eval
use ofort_binding, only: ofort_interpreter
implicit none
type(ofort_interpreter) :: interp
integer :: rc
real(8) :: y

call interp%create()
rc = interp%execute(“integer :: n = 2; print*,n**5”)
call check()
write (*, ‘(a)’, advance=‘no’) interp%output()

call interp%reset()
call interp%set_trace_assign(.true.)
rc = interp%execute(“integer :: x; x = 7 * 8”)
call check()
write (*, ‘(a)’, advance=‘no’) interp%warnings()

call interp%reset()
rc = interp%execute("real function f(x); real :: x; f = xx + 1; end")
call check()
y = interp%call_real1(“f”, 3.0d0)
write (, ‘(g0)’) y
call interp%destroy()

contains
subroutine check()
if (rc /= 0) then
write (*, ‘(a)’) trim(interp%error())
stop 1
end if
end subroutine check
end program demo_eval

```

and get output

`32`  
`56`  
`10.000000000000000`
