Add Fortran reading files and method pages

This commit is contained in:
Rasmus Rasmussen 2025-02-25 11:15:11 +01:00
parent 33b2f14cb8
commit 663ac1cff6
7 changed files with 192 additions and 14 deletions

View File

@ -0,0 +1,171 @@
<template>
<page-start>Calls, Methods, Functions and Subroutines</page-start>
<paragraph>In Fortran, there is no such thing as methods, but functions and subroutines instead. Fortran, compared to
other C-like programming languages, executes functions and subroutines differently. And what even is a subroutine?
Well, fret not, for we will discuss that in this post.<br><br>
<code-tag>function</code-tag>s are pretty much the same as methods in newer programming languages. They take in an input, and return an
output. They can also just take an input, and save it to a file. Or they could also just return a constant value.
At the end of the day, it's just a piece of code that is usually reused between multiple parts of the program.<br><br>
<code-tag>subroutine</code-tag>s are almost the exact same as functions. One such difference is that subroutine doesn't return anything,
in the traditional sense. If functions return a modified version of the input, a subroutine modifies the input data
in place.<br><br>
A subroutines parameters are often annotated inside the code block, with an intent. Observe the code below:</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
module PlusHelper
implicit none
public :: plus_two
contains
subroutine plus_two (number)
integer, intent (out) :: number
number = number + 2
end subroutine plus_two
end module PlusHelper
</code></pre>
</div>
<paragraph>It's fairly easy to understand, really. We tell the compiler that <code-tag>number</code-tag> is intended
to be used and modified. <code-tag>intent()</code-tag> is a keyword used to hint and guide the compiler in what to do
with the value, deep down when compiling to machine code.<br><br>
<code-tag>in</code-tag> tells the compiler that the value is only used, but not modified. <code-tag>out</code-tag>
tells the compiler that the value is returned to the caller. We'll show how it's returned later on. <code-tag>inout</code-tag>
tells the compiler that the value is used, modified and then returned.<br><br>
As we can see with the code, <code-tag>number</code-tag> is being added by 2, and then returned. We'll see how the
value is used in the caller later.<br><br>
Let's show another example, that showcases this functionality a little better:</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
module MultiplyHelper
implicit none
public :: multiply_by
contains
subroutine multiply (number, multiply)
integer, intent(out) :: number
integer, intent(in) :: multiply
number = number * multiply
end subroutine multiply
end module MultiplyHelper
</code></pre>
</div>
<paragraph>As we can see with the code, it just returns the <code-tag>number</code-tag> after it has been multiplied by
the <code-tag>multiply</code-tag> value. Now let's see how we call the subroutine:</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
program hello
use PlusHelper, only: plus_two
use MultiplyHelper, only: multiply_by
implicit none
integer :: number = 5
print *, number
call plus_two(number)
print *, number
call multiply_by(number, 2)
print *, number
end program hello
</code></pre>
</div>
<paragraph>And the output looks like this:</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
$ ./main
5
7
14
</code></pre>
</div>
<paragraph>That was pretty simply. That's how subroutines works. Now let's go over functions. First we start by defining
out function.</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
function divide_by(number, divide) result(return)
integer, intent(in) :: number
integer, intent(in) :: divide
integer :: return
return = number / divide
end function divide_by
</code></pre>
</div>
<paragraph>As we can see, it's almost like we're defining a subroutine. Do notice that we're still using the
<code-tag>intent</code-tag> keyword. We define out return as an integer as well. Also note that we're dividing integers,
and not floats. So the numbers are prone to rounding.<br><br>
Let's take a look on how we call a function.</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
program hello
use PlusHelper, only: plus_two
use MultiplyHelper, only: multiply_by
implicit none
integer :: divide_by
integer :: number = 5
print *, number
call plus_two(number)
print *, number
call multiply_by(number, 2)
print *, number
print *, divide_by(number, 2)
end program hello
</code></pre>
</div>
<paragraph>We create an <code-tag>integer</code-tag> that serves as the return for out function <code-tag>divide_by(n, k)</code-tag>.
And we call it just by writing the function name with it's parameters.<br><br>
The output looks like this:
</paragraph>
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
<pre><code class="text-sm">
$ ./main
5
7
14
7
</code></pre>
</div>
<paragraph>TLDR: Functions are assigned as variables, and subroutines are imported and called with the <code-tag>call</code-tag> keyword.</paragraph>
</template>
<script setup lang="ts">
import PageStart from "../../../tags/PageStart.vue";
import Paragraph from "../../../tags/Paragraph.vue";
import CodeTag from "../../../tags/CodeTag.vue";
</script>

View File

@ -24,6 +24,7 @@
<li><RouterLink to="/Fortran/SetUp">&gt; Set Up</RouterLink></li> <li><RouterLink to="/Fortran/SetUp">&gt; Set Up</RouterLink></li>
<li><RouterLink to="/Fortran/HelloWorld">&gt; Hello World</RouterLink></li> <li><RouterLink to="/Fortran/HelloWorld">&gt; Hello World</RouterLink></li>
<li><RouterLink to="/Fortran/DataTypes">&gt; Data Types</RouterLink></li> <li><RouterLink to="/Fortran/DataTypes">&gt; Data Types</RouterLink></li>
<li><RouterLink to="/Fortran/Methods">&gt; Method, Functions, Sub Routines and Calls</RouterLink></li>
<li><RouterLink to="/Fortran/ReadingAFile">&gt; Reading A File</RouterLink></li> <li><RouterLink to="/Fortran/ReadingAFile">&gt; Reading A File</RouterLink></li>
</ul> </ul>
</div> </div>

View File

@ -1,15 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import PageStart from "../../../tags/PageStart.vue";
import CodeTag from "../../../tags/CodeTag.vue";
</script> </script>
<template> <template>
<div> <div>
<h1 class="text-3xl">Reading A File In Fortran 90</h1> <page-start>Reading A File In Fortran 90</page-start>
<hr>
<p></p>
<code class=""> <p class="mb-6">Reading files in high level programming languages is rather easy. I C#, you would just create a
<code-tag>StreamReader</code-tag> object, and execute: <code-tag>streamReader.ReadLine()</code-tag> and bam,
you've read the first line of the file. Now just check if the string returned is null, in a while loop, and you've
read the whole file. Easy peasy.<br><br>
</code> In Fortran 90, however, there is a little more than that. Not a lot more, to be honest, but there is a little more.</p>
</div> </div>
</template> </template>

View File

@ -12,6 +12,8 @@ import FortranReadingFiles from "./components/Fortran/Fortran_Reading_Files.vue"
import FortranHelloWorld from "./components/Fortran/Fortran_Hello_World.vue"; import FortranHelloWorld from "./components/Fortran/Fortran_Hello_World.vue";
import FortranSetUp from "./components/Fortran/Fortran_Set_Up.vue"; import FortranSetUp from "./components/Fortran/Fortran_Set_Up.vue";
import FortranDataTypes from "./components/Fortran/Fortran_Data_Types.vue"; import FortranDataTypes from "./components/Fortran/Fortran_Data_Types.vue";
import FortranCallsMethodsFunctionsSubroutines
from "./components/Fortran/Fortran_Calls_Methods_Functions_Subroutines.vue";
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
@ -23,6 +25,7 @@ const router = createRouter({
{path: '/Fortran/SetUp', name: 'SetUp', component: FortranSetUp}, {path: '/Fortran/SetUp', name: 'SetUp', component: FortranSetUp},
{path: '/Fortran/HelloWorld', name: 'HelloWorld', component: FortranHelloWorld}, {path: '/Fortran/HelloWorld', name: 'HelloWorld', component: FortranHelloWorld},
{path: '/Fortran/DataTypes', name: 'DataTypes', component: FortranDataTypes}, {path: '/Fortran/DataTypes', name: 'DataTypes', component: FortranDataTypes},
{path: '/Fortran/Methods', name: 'Methods', component: FortranCallsMethodsFunctionsSubroutines},
{path: '/Fortran/ReadingAFile', name: 'ReadingAFile', component: FortranReadingFiles}, {path: '/Fortran/ReadingAFile', name: 'ReadingAFile', component: FortranReadingFiles},
{path: '/Pascal', name: 'Pascal', component: PascalIndex}, {path: '/Pascal', name: 'Pascal', component: PascalIndex},

View File

@ -1,11 +1,3 @@
<script setup lang="ts">
</script>
<template> <template>
<code class="text-red-500"><slot></slot></code> <code class="text-red-500"><slot></slot></code>
</template> </template>
<style scoped>
</style>

4
tags/PageStart.vue Normal file
View File

@ -0,0 +1,4 @@
<template>
<h1 class="text-3xl"><slot></slot></h1>
<hr class="mb-6">
</template>

3
tags/Paragraph.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
<p class="mb-6"><slot></slot></p>
</template>