Compare commits
13 Commits
ancient_to
...
main
Author | SHA1 | Date | |
---|---|---|---|
32b85f26b7 | |||
633e5a4c64 | |||
7f8dcdd239 | |||
fad887762e | |||
aa204ec981 | |||
688531adfc | |||
663ac1cff6 | |||
33b2f14cb8 | |||
f8a6148ac7 | |||
3bd11d29c4 | |||
77a2e6edcf | |||
3920ab81c7 | |||
a4b2d1378e |
64
src/App.vue
64
src/App.vue
@ -1,65 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {ref} from "vue";
|
||||
|
||||
const toolbar = ref<boolean>(false);
|
||||
const canGoForward = ref<boolean>(false);
|
||||
const canGoBack = ref<boolean>(false);
|
||||
|
||||
function activateToolbar() {
|
||||
toolbar.value = !toolbar.value;
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
canGoBack.value = window.history.length <= 1;
|
||||
history.back();
|
||||
}
|
||||
|
||||
function goForward() {
|
||||
canGoForward.value = window.history.length <= 1;
|
||||
history.forward();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<div class="flex flex-col min-h-screen bg-var_background">
|
||||
|
||||
<div v-if="toolbar">
|
||||
<div class="w-full py-small bg-ancient_highlight shadow-xl"></div>
|
||||
<div class="w-full py-small bg-ancient_shadow"></div>
|
||||
<div class="flex justify-center bg-ancient">
|
||||
<div class="w-full max-w-screen-lg px-4">
|
||||
<button @click="goBack" v-if="canGoBack">
|
||||
<img src="/public/Icons/toolbar/Back.avif" width="32px" height="32px" class="mx-2" alt="Ancient looking back button">
|
||||
</button>
|
||||
|
||||
<button @click="goBack" v-if="!canGoBack" disabled>
|
||||
<img src="/public/Icons/toolbar/Back_Gray.avif" width="32px" height="32px" class="mx-2" alt="Ancient looking back button">
|
||||
</button>
|
||||
|
||||
<button @click="goForward" v-if="canGoForward">
|
||||
<img src="/public/Icons/toolbar/Forward.avif" width="32px" height="32px" class="mx-2" alt="Ancient looking forward button">
|
||||
</button>
|
||||
|
||||
<button @click="goForward" v-if="!canGoForward" disabled>
|
||||
<img src="/public/Icons/toolbar/Forward_Gray.avif" width="32px" height="32px" class="mx-2" alt="Ancient looking forward button">
|
||||
</button>
|
||||
|
||||
<button><img src="/public/Icons/toolbar/Refresh.avif" width="20px" height="32px" class="mx-2" alt="Ancient looking forward button"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full py-small bg-ancient_highlight shadow-xl"></div>
|
||||
<div class="w-full py-small bg-ancient_shadow"></div>
|
||||
</div>
|
||||
|
||||
<header class="flex justify-center">
|
||||
<nav class="pt-10 text-2xl flex place-items-center">
|
||||
<RouterLink class="mx-1" to="/">Home</RouterLink> |
|
||||
<RouterLink class="mx-1" to="/About">About</RouterLink> |
|
||||
<RouterLink class="mx-1" to="/Fortran">Fortran</RouterLink> |
|
||||
<RouterLink class="mx-1" to="/Pascal">Pascal</RouterLink> |
|
||||
<RouterLink class="mx-1" to="/Lisp">Lisp</RouterLink>
|
||||
<RouterLink class="mx-1" to="/">Home</RouterLink>
|
||||
<RouterLink class="mx-1" to="/C">C</RouterLink>
|
||||
<RouterLink class="mx-1" to="/Fortran">Fortran</RouterLink>
|
||||
<RouterLink class="mx-1" to="/About">About</RouterLink>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@ -71,7 +18,6 @@ function goForward() {
|
||||
|
||||
<footer class="flex justify-center pt-10 mt-10 pb-2">
|
||||
<h5>Author: Still under construction</h5>
|
||||
<button @click="activateToolbar">Time travel</button>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
@ -1,71 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Paragraph from "./tags/Paragraph.vue";
|
||||
import PageStart from "./tags/PageStart.vue";
|
||||
import CodeTag from "./tags/CodeTag.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl">About This Page</h1>
|
||||
<hr>
|
||||
<p>This page is about ancient (before the year 2000) programming languages, like Fortran and C. This page is mostly
|
||||
<page-start>About This Page</page-start>
|
||||
|
||||
<paragraph>This page is about ancient (before the year 2000) programming languages, like Fortran and C. This page is mostly
|
||||
about showing how it was done before fancy build tools and syntax were a thing. It also serves a purpose of a
|
||||
showing, with examples, how to not only set up the programming environments, but also the whole workflow from
|
||||
prototype to production.</p>
|
||||
<br>
|
||||
prototype to production.<br><br>
|
||||
|
||||
<p>This whole idea started when I made my first "serious" blog, <a class="underline" href="https://rbwr.dk">rbwr.dk</a>, but it didn't
|
||||
This whole idea started when I made my first "serious" blog, <a class="underline" href="https://rbwr.dk">rbwr.dk</a>, but it didn't
|
||||
feel like quite the "correct" place to put it. So the idea was shelved for a time... Until recently, when I picked
|
||||
up a project in Fortran. Yep, Fortran. I had gotten bored, and wanted to challenge myself. And I thought, that if
|
||||
I'm going to learn the language, I might as well put blood, sweat and tears into formulating and showcasing how
|
||||
it's done (correctly).</p>
|
||||
<br>
|
||||
it's done (correctly).<br><br>
|
||||
|
||||
<p>I did initially want to try COBOL, but after looking at some examples, Fortran kind of looked more appealing lol.</p>
|
||||
<br>
|
||||
<br>
|
||||
I did initially want to try COBOL, but after looking at some examples, Fortran kind of looked more appealing lol.</paragraph>
|
||||
|
||||
<h1 class="text-3xl">Who Am I?</h1>
|
||||
<h2 class="text-3xl">Who Am I?</h2>
|
||||
<hr>
|
||||
<p>My name is Rasmus Rasmussen (yes, that's my name), I live somewhere in the outskirts of Odense, Denmark, and I'm primarily
|
||||
|
||||
<paragraph>My name is Rasmus Rasmussen (yes, that's my name), I live somewhere in the outskirts of Odense, Denmark, and I'm primarily
|
||||
a backend developer. But lately, I've started to like developing in vue3. With TypeScript, of cause. It's a nice
|
||||
chance of pace, and I often find myself wanting to experiment with different styling, as well as trying to
|
||||
optimize and minimize my bundles.</p>
|
||||
<br>
|
||||
optimize and minimize my bundles.<br><br>
|
||||
|
||||
<p>I'm an educated datamatiker from UCL Erhvervsakademi og Professionshøjskole. (I have no idea what it's called
|
||||
I'm an educated datamatiker from UCL Erhvervsakademi og Professionshøjskole. (I have no idea what it's called
|
||||
in English). Doing my study, I have primarily developed in C# and .NET, as well as ASPNET, JavaScript, SQL and
|
||||
Umbraco. I have also set up multiple Linux unmanaged servers, together with Docker, that I use to host my websites
|
||||
and web-application.</p>
|
||||
<br>
|
||||
and web-application.<br><br>
|
||||
|
||||
<p>In my free time, I like to write blog posts about small, or sometimes big, project. It can be about anything,
|
||||
In my free time, I like to write blog posts about small, or sometimes big, project. It can be about anything,
|
||||
really. The most important part is that I learn something. Like with my project
|
||||
<a class="underline" href="https://rbwr.dk/posts/setting_up_a_new_blazor_interactive_server_side_render_project/">where I was setting
|
||||
up a Blazor Interactive SSR web app.</a> I learned quite a lot doing that project. For example how to handle file
|
||||
upload, or some of the newer C# syntax, like the "Index from end expression" that looks like this <code>[^1]</code></p>
|
||||
<br>
|
||||
upload, or some of the newer C# syntax, like the "Index from end expression" that looks like this: <code-tag>[^1]</code-tag><br><br>
|
||||
|
||||
<p>Another project I'm also quite proud of, is my own custom search engine. Or well, it was supposed to be a search
|
||||
Another project I'm also quite proud of, is my own custom search engine. Or well, it was supposed to be a search
|
||||
engine, but ended up as a crawler, that collects statistics of various metrics, such as response codes, server
|
||||
type, Tls version, Etc. It's still running, as the IPv4 space is quite large. Some of the best aspects of the
|
||||
projects, was that I learned how to optimally handle high amounts of threads (up to 256 threads) for the scanner
|
||||
to use, when finding websites on the internet.</p>
|
||||
<br>
|
||||
to use, when finding websites on the internet.<br><br>
|
||||
|
||||
<p>A little more about me :) I like to bike. I have a normal, bog-standard bike cycle, that I like to bike large
|
||||
A little more about me :) I like to bike. I have a normal, bog-standard bike cycle, that I like to bike large
|
||||
distances with. I try to aim at 80Km and as early as possible. Usually, when biking those distances, I aim to
|
||||
start the journey at 5 in the morning. It gives a good jolt of energy, when the morning fog hits. Plus, when
|
||||
start that early on, you usually find some pretty cool scenes. Like this image I took at 5:30 in the morning, not
|
||||
too far from my apartment.</p>
|
||||
<br>
|
||||
too far from my apartment.</paragraph>
|
||||
|
||||
<img src="/public/Images/avif/PXL_20230708_030149199_scaled.avif" alt="Meadow with fog." loading="lazy" decoding="async" width="1434" height="1080">
|
||||
<p>Not bad huh? The things you see when everyone is asleep.</p>
|
||||
<br>
|
||||
<img src="/Images/avif/PXL_20230708_030149199_scaled.avif" alt="Meadow with fog." loading="lazy" decoding="async" width="1434" height="1080">
|
||||
<paragraph>Not bad huh? The things you see when everyone is asleep.</paragraph>
|
||||
|
||||
<img src="/public/Images/avif/PXL_20230720_032828882_scaled.avif" alt="My humble bike." loading="lazy" decoding="async" width="1434" height="1080">
|
||||
<p>And this is my humble bike. It has taken me many places, and it's still going strong. The odometer no longer works,
|
||||
<img src="/Images/avif/PXL_20230720_032828882_scaled.avif" alt="My humble bike." loading="lazy" decoding="async" width="1434" height="1080">
|
||||
<paragraph>And this is my humble bike. It has taken me many places, and it's still going strong. The odometer no longer works,
|
||||
so I just use my FitBit Charge 5 instead. I've modeled and 3D printed the two orange bottle holders myself, on my
|
||||
Original Prusa MK3S+.</p>
|
||||
</div>
|
||||
|
||||
Original Prusa MK3S+.</paragraph>
|
||||
</template>
|
9
src/components/C/C_Hello_World.vue
Normal file
9
src/components/C/C_Hello_World.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-start>Hello World In Fortran 90</page-start>
|
||||
|
||||
</template>
|
28
src/components/C/C_Index.vue
Normal file
28
src/components/C/C_Index.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-start>C</page-start>
|
||||
|
||||
<paragraph>C is one of those ancient languages that's still getting used to this very day. It's a language from
|
||||
the year 1972, making it 53 years young as of 2025. It originated at Bell Labs, and was developed with the purpose of
|
||||
creating utilities for Unix.<br><br>
|
||||
|
||||
In the 80s, C steadily became more and more accepted as the go-to language. Especially with kernel and driver code.
|
||||
The Linux kernel is one such huge project written in almost purely C, although in recent times, the kernel is introducing
|
||||
Rust code.
|
||||
</paragraph>
|
||||
|
||||
<p>Table of contents:</p>
|
||||
<ul>
|
||||
<li><RouterLink to="/C/SetUp">> Set Up</RouterLink></li>
|
||||
<li><RouterLink to="/C/SetUp">> Hello World</RouterLink></li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
170
src/components/C/C_Set_Up.vue
Normal file
170
src/components/C/C_Set_Up.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-start>Setting Up The Environment</page-start>
|
||||
|
||||
<paragraph>
|
||||
If you're familiar Fortran, then this guide will be quite easy for you. For C, there isn't really an "official"
|
||||
compiler, but there are compilers that implement the standards of C. For this guide, we'll be using GCC. There are
|
||||
other great compilers, such as clang.<br><br>
|
||||
|
||||
Just like with the <RouterLink to="/Fortran/SetUp">Fortran set up guide</RouterLink>, we'll be doing this on Fedora
|
||||
Linux, but other distros, like Ubuntu, would work just as well.
|
||||
</paragraph>
|
||||
|
||||
<p>For Fedora:</p>
|
||||
<code-tag>$ sudo dnf install gcc</code-tag>
|
||||
|
||||
<p>For ubuntu:</p>
|
||||
<code-tag>$ sudo apt install build-essential</code-tag>
|
||||
|
||||
<paragraph>Easy peasy.</paragraph>
|
||||
|
||||
<h2 class="text-2xl">Project Structure</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph>For any big C projects, a project structure is very important. It helps to organize and keep track of our
|
||||
code. But for smaller projects, or just for testing purposes, a project structure could be too
|
||||
redundant.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
project/
|
||||
├── src/ # Source files (*.c, main.c)
|
||||
│ └── main.c # Main program file
|
||||
├── include/ # Header files (*.h)
|
||||
├── lib/ # Library object files and archives
|
||||
├── bin/ # Executable binaries
|
||||
├── build/ # Temporary files (*.o)
|
||||
├── tests/ # Test files
|
||||
└── Makefile # Build script
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl">Compiling</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph>
|
||||
Makefiles are very useful, and becomes increasingly useful, the bigger the project gets. A makefile simplifies the
|
||||
compilation process, as all of the compile flags can be gathered inside a single file. It makes it possible to
|
||||
dynamically change the compilation depending on the system architecture or config. It also removes the need to
|
||||
manually compile and link your objects together, every time you make a change.<br><br>
|
||||
|
||||
And with a bigger project, comes a big count of source files. That's where a makefile helps a lot, as it handles
|
||||
and tracks all changes to each file, ensuring that it's only the changed files that gets re-compiled.<br><br>
|
||||
|
||||
So let's see a makefile in action. Below code is a simple Hello World application, that we will use a makefile to
|
||||
compile. Although it's worth noting, that a program this small, a makefile is wildly redundant. But it does show
|
||||
how it's set up in a simple environment.<br><br>
|
||||
|
||||
With this little example, we're doing a Hello World program, but fret not, we'll go into details in a later guide.
|
||||
</paragraph>
|
||||
|
||||
<code-tag>hello.c</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
#include <stdio.h>
|
||||
|
||||
int main(){
|
||||
printf("Hello, World!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<code-tag>Makefile</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
# Makefile for hello.c
|
||||
|
||||
CC = gcc # C compiler
|
||||
CFLAGS = -O2 # Compiler flags (optimization level)
|
||||
|
||||
hello: hello.o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
hello.o: hello.c
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
run:
|
||||
./hello
|
||||
|
||||
clean:
|
||||
rm -f *.o hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>
|
||||
For anyone not programming in a language that uses the <code-tag>make</code-tag> makefile, this might look rather off-putting.
|
||||
But worry not, because at the end of the day, it's simply just some rules, that the compiler follows to compile your program.
|
||||
</paragraph>
|
||||
|
||||
<ul class="mb-6">
|
||||
<li>> <code-tag>hello: hello.o</code-tag></li>
|
||||
<li class="pb-2">> > Here, the program "hello" depends on the object file "hello.o".</li>
|
||||
|
||||
<li>> <code-tag>$(CC) $(CFLAGS) -o $@ $^</code-tag></li>
|
||||
<li class="pb-2">> > This one compiles the object files into the program.</li>
|
||||
|
||||
<li>> <code-tag>hello.o: hello.c</code-tag></li>
|
||||
<li class="pb-2">> > Here, the object file "hello.o" depends on the source file "hello.c".</li>
|
||||
|
||||
<li>> <code-tag>$(CC) $(CFLAGS) -c $<</code-tag></li>
|
||||
<li class="pb-2">> > This one compiles the source files into the object files.</li>
|
||||
|
||||
<li>> <code-tag>run: ./hello</code-tag></li>
|
||||
<li class="pb-2">> > This runs the program if you execute <code-tag>make run</code-tag></li>
|
||||
|
||||
<li>> <code-tag>clean: rm -f *.o hello</code-tag></li>
|
||||
<li class="pb-2">> > Here, the object files gets removed when running <code-tag>make clean</code-tag></li>
|
||||
</ul>
|
||||
|
||||
<paragraph>
|
||||
A quick note. It's very important that whenever something is indented in a makefile, that it's indented with a tab,
|
||||
and not 4 spaces. It needs to be a tab character.<br><br>
|
||||
|
||||
Now simply run the makefile with the following command.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ make
|
||||
gcc -O2 -c hello.c
|
||||
gcc -O2 -o hello hello.o
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>
|
||||
We have now successfully compiled the program with the help of a makefile. Now simply run the program and we'll
|
||||
see the output.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ ./hello
|
||||
Hello, World!
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>If we run <code-tag>make run</code-tag> command instead, the output should look pretty much the same.</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ make run
|
||||
./hello
|
||||
Hello, World!
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,169 @@
|
||||
<script setup lang="ts">
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
</script>
|
||||
|
||||
<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 class="font-bold">TLDR: Functions are assigned as variables, and subroutines are imported and called with the <code-tag>call</code-tag> keyword.</paragraph>
|
||||
|
||||
</template>
|
419
src/components/Fortran/Fortran_Data_Types.vue
Normal file
419
src/components/Fortran/Fortran_Data_Types.vue
Normal file
@ -0,0 +1,419 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-start>Data Types</page-start>
|
||||
|
||||
<paragraph>Just like any other programming language that has datatypes, Fortran has datatypes as well. The big difference, from
|
||||
other languages, of cause, is how they're created and assigned. If you're a developer of, for example, C#, Java or
|
||||
even Python, you will feel the difference pretty fast.<br><br>
|
||||
|
||||
Let's look at a small list of some common types.</paragraph>
|
||||
|
||||
<ul class="mb-6">
|
||||
<li>> <CodeTag>integer</CodeTag></li>
|
||||
<li>> <code-tag>real</code-tag></li>
|
||||
<li>> <code-tag>double precision</code-tag></li>
|
||||
<li>> <code-tag>logical</code-tag></li>
|
||||
<li>> <code-tag>character</code-tag></li>
|
||||
</ul>
|
||||
|
||||
<paragraph><code-tag>integer</code-tag> is, if you hadn't guessed, a whole number. Like most languages,
|
||||
<code-tag>int</code-tag>. The <code-tag>real</code-tag> type is like a
|
||||
<code-tag>float</code-tag>. But the difference with Fortran types, in general, is that you have "less" types,
|
||||
but you have more control over those types, making it essentially the same as if you had more types. More on that later.<br><br>
|
||||
|
||||
The <code-tag>double precision</code-tag> is a double, obviously. And as you have probably guessed at
|
||||
this point, <code-tag>logical</code-tag> is a boolean. <code-tag>character</code-tag>
|
||||
however, is a little bit different. In "new" programming terms, it would be an array of characters that behaves
|
||||
like a string. Or like in SQL: <code-tag>VARCHAR(256)</code-tag>.</paragraph>
|
||||
|
||||
<h2 class="text-2xl">integer</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph>In Fortran, you can specify the size of an integer at declaration. You do that with <code-tag>(kind = n)</code-tag>.
|
||||
So if you want a 16 bit integer, you do <code-tag>integer(kind = 16)</code-tag>. Observe the following code example.
|
||||
As an exercise for the reader, try to imagine what would be printed to the terminal.<br><br>
|
||||
|
||||
*Do note that we're using Fortran 90, and not the newer versions that supports unsigned integers.<a href="#footnote-1">[1]</a>
|
||||
</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
integer :: int1;
|
||||
integer(kind = 2) :: int2;
|
||||
integer(kind = 4) :: int4;
|
||||
integer(kind = 8) :: int8;
|
||||
integer(kind = 16) :: int16;
|
||||
|
||||
print *, 'int'
|
||||
print *, huge(int1)
|
||||
print *
|
||||
print *, 'kind = 2'
|
||||
print *, huge(int2)
|
||||
print *
|
||||
print *, 'kind = 4'
|
||||
print *, huge(int4)
|
||||
print *
|
||||
print *, 'kind = 8'
|
||||
print *, huge(int8)
|
||||
print *
|
||||
print *, 'kind = 16'
|
||||
print *, huge(int16)
|
||||
|
||||
end program hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Now, as the astute reader might have already figured, the output would look like this:</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
int
|
||||
2147483647
|
||||
|
||||
kind = 2
|
||||
32767
|
||||
|
||||
kind = 4
|
||||
2147483647
|
||||
|
||||
kind = 8
|
||||
9223372036854775807
|
||||
|
||||
kind = 16
|
||||
170141183460469231731687303715884105727
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>The <code-tag>huge(n)</code-tag> function simply assigns the highest largest number of any integer,
|
||||
real or array type of any kind.<br><br>
|
||||
|
||||
Any integer without a kind, is automatically a 4 byte integer. Integers with kind 2, is 2 bytes big. Integers with
|
||||
kind 4 is 4 bytes big. And so on and so forth.<br><br>
|
||||
|
||||
Usually, unless your working with huge datasets, <code-tag>integer</code-tag> or if you want to be more semantic,
|
||||
<code-tag>integer(kind = 4)</code-tag> would be more than sufficient to work with.</paragraph>
|
||||
|
||||
<h2 class="text-2xl">real</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph>The <code-tag>real</code-tag> type is, in most other languages, a <code-tag>float</code-tag>. And with
|
||||
integers, real can also be specified with a <code-tag>kind(n)</code-tag> modifier. Observe this example:</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
real :: real1;
|
||||
real(kind = 4) real4;
|
||||
real(kind = 8) real8;
|
||||
real(kind = 16) real16;
|
||||
|
||||
print *, 'real'
|
||||
print *, huge(real1)
|
||||
print *, tiny(real1)
|
||||
print *
|
||||
print *, 'kind = 4'
|
||||
print *, huge(real4)
|
||||
print *, tiny(real4)
|
||||
print *
|
||||
print *, 'kind = 8'
|
||||
print *, huge(real8)
|
||||
print *, tiny(real8)
|
||||
print *
|
||||
print *, 'kind = 16'
|
||||
print *, huge(real16)
|
||||
print *, tiny(real16)
|
||||
|
||||
end program hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>The output:</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
real
|
||||
3.40282347E+38
|
||||
1.17549435E-38
|
||||
|
||||
real(kind = 4)
|
||||
3.40282347E+38
|
||||
1.17549435E-38
|
||||
|
||||
real(kind = 8)
|
||||
1.7976931348623157E+308
|
||||
2.2250738585072014E-308
|
||||
|
||||
real(kind = 16)
|
||||
1.18973149535723176508575932662800702E+4932
|
||||
3.36210314311209350626267781732175260E-4932
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>As you can see here, we have included a new print statement. <code-tag>tiny(n)</code-tag> returns
|
||||
the smallest positive number of a real kind. That function is not available for integers.</paragraph>
|
||||
|
||||
<h2 class="text-2xl">double precision</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph><code-tag>double precision</code-tag> is pretty much just a bigger version of real. All of the same rules apply
|
||||
to double precision as the real type.</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
double precision :: double;
|
||||
|
||||
print *, 'real'
|
||||
print *, huge(double)
|
||||
print *, tiny(double)
|
||||
|
||||
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">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
real
|
||||
1.7976931348623157E+308
|
||||
2.2250738585072014E-308
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph><code-tag>double precision</code-tag> does not support the kind modifier. A double precision number is
|
||||
also the same as an 8 byte real.</paragraph>
|
||||
|
||||
<h2 class="text-2xl">logical</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph><code-tag>logical</code-tag> is a boolean. It's either true or false. But a funny thing with the logical type in
|
||||
Fortran, compared to other languages, is that you can define the size of it. The logical type supports the
|
||||
<code-tag>kind(n)</code-tag> modifier.<br><br>
|
||||
|
||||
A good reason for the different sized logical, is optimization. Some systems handles larger object better than smaller,
|
||||
or some systems handles smaller objects better. It all depends on the architecture.</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
logical :: bool;
|
||||
logical(kind = 1) :: bool1;
|
||||
logical(kind = 2) :: bool2;
|
||||
logical(kind = 4) :: bool4;
|
||||
logical(kind = 8) :: bool8;
|
||||
logical(kind = 16) :: bool16;
|
||||
|
||||
print *, 'logical'
|
||||
print *, 'value: ', bool
|
||||
print *, 'size: ', sizeof(bool)
|
||||
print *
|
||||
print *, 'value: ', bool1
|
||||
print *, 'size: ', sizeof(bool1)
|
||||
print *
|
||||
print *, 'value: ', bool2
|
||||
print *, 'size: ', sizeof(bool2)
|
||||
print *
|
||||
print *, 'value: ', bool4
|
||||
print *, 'size: ', sizeof(bool4)
|
||||
print *
|
||||
print *, 'value: ', bool8
|
||||
print *, 'size: ', sizeof(bool8)
|
||||
print *
|
||||
print *, 'value: ', bool16
|
||||
print *, 'size: ', sizeof(bool16)
|
||||
|
||||
end program hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Now I have a small exercise for the reader again. Let's assume that we are using <code-tag>gfortran</code-tag>
|
||||
without specifying an optimization level. What do you think the output would look like?</paragraph>
|
||||
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
logical
|
||||
value: T
|
||||
size: 4
|
||||
|
||||
value: T
|
||||
size: 1
|
||||
|
||||
value: T
|
||||
size: 2
|
||||
|
||||
value: T
|
||||
size: 4
|
||||
|
||||
value: F
|
||||
size: 8
|
||||
|
||||
value: T
|
||||
size: 16
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Huh, that was weird. The 8 bit logical is false, while the others are true. The reason for this behavior
|
||||
could be a multitude of things. One could be optimization, as the compiler tries to make the program faster. And
|
||||
by setting the 8 bit logical to false. It could also be how an unassigned logical is represented. For more information,
|
||||
check the footnote number 2. <a href="#footnote-1">[2]</a><br><br>
|
||||
|
||||
A good programming practise is to always assign your logical when creating them.</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
logical :: bool = .true.;
|
||||
logical(kind = 1) :: bool1 = .true.;
|
||||
logical(kind = 2) :: bool2 = .true.;
|
||||
logical(kind = 4) :: bool4 = .true.;
|
||||
logical(kind = 8) :: bool8 = .true.;
|
||||
logical(kind = 16) :: bool16 = .true.;
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Now, the output looks as expected.</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
logical
|
||||
value: T
|
||||
size: 4
|
||||
|
||||
value: T
|
||||
size: 1
|
||||
|
||||
value: T
|
||||
size: 2
|
||||
|
||||
value: T
|
||||
size: 4
|
||||
|
||||
value: T
|
||||
size: 8
|
||||
|
||||
value: T
|
||||
size: 16
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl">character</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph><code-tag>character</code-tag> in fortran can be seen as either a <code-tag>char</code-tag> or
|
||||
a <code-tag>string</code-tag> in other languages, depending on the length you give it.<br><br>
|
||||
|
||||
Observe the example below.</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
character :: char;
|
||||
character(len = 10) :: char2 = 'a';
|
||||
|
||||
print *, 'character';
|
||||
print *, 'value: ', char;
|
||||
print *, 'size: ', sizeof(char);
|
||||
print *
|
||||
print *, 'value: ', char2;
|
||||
print *, 'size: ', sizeof(char2);
|
||||
print *
|
||||
print *, 'value: ', char2//'lol';
|
||||
print *, 'size: ', sizeof(char2);
|
||||
|
||||
end program hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Output looks like this:</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
character
|
||||
value: 4
|
||||
size: 1
|
||||
|
||||
value: a
|
||||
size: 10
|
||||
|
||||
value: a lol
|
||||
size: 10
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>lol. With Fortran, if you create a character, with a certain size, but only assign it a smaller vallue,
|
||||
the trailing indexes in the character will be filled with whitespace.<br><br>
|
||||
|
||||
To mitigate this, we could either set the correct length when creating the character, or we could use the <code-tag>trim(value)</code-tag>
|
||||
function. It removes trailing whitespaces from strings.</paragraph>
|
||||
|
||||
<code-tag>main.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
trim(char2)//'lol';
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>Now, the output should be fixed:</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
> gfortran main.f90
|
||||
> ./a.out
|
||||
character
|
||||
value:
|
||||
size: 1
|
||||
|
||||
value: a
|
||||
size: 10
|
||||
|
||||
value: a lol
|
||||
size: 10
|
||||
|
||||
with trim
|
||||
value: alol
|
||||
size: 10
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<p>Footnotes:</p>
|
||||
<ul>
|
||||
<li id="footnote-1">[1] <a href="https://gcc.gnu.org/onlinedocs/gfortran/Unsigned-integers.html" class="underline">unsigned integers with gfortran</a></li>
|
||||
<li id="footnote-2">[2] <a href="https://stackoverflow.com/a/71190625" class="underline">Why would using uninitialized variables in Fortran ever work? [duplicate]</a></li>
|
||||
</ul>
|
||||
</template>
|
@ -1,45 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl">Hello World In Fortran 90</h1>
|
||||
<hr>
|
||||
<p></p>
|
||||
<page-start>Hello World In Fortran 90</page-start>
|
||||
|
||||
<div class="font-mono">
|
||||
<pre><code class="text-sm">
|
||||
<paragraph>A Hello World program is always a great step into a new programming language. It gives a simple oversight into
|
||||
the build process of said language. And with a simple project come a simple intro (mostly). But fret not, Fortran
|
||||
can be simple or complex, depending on the size of the project.</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
print *, 'Hello world!'
|
||||
end program hello
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<p>In the good ol' days (before FORTRAN 77), when printing to console, you would write <span><code>write(*,*)</code></span>,
|
||||
but with the release of FORTRAN 77, that became redundant, as you could use the newest keyword: <span><code>print</code></span>.</p>
|
||||
<br>
|
||||
<paragraph>In the good ol' days (before FORTRAN 77), when printing to console, you would write <code-tag>write(*,*)</code-tag>,
|
||||
but with the release of FORTRAN 77, that became redundant, as you could use the newest keyword: <code-tag>print</code-tag>. <br><br>
|
||||
|
||||
<p>With modern compilers, running the newest Fortran standards, <span><code>write(*,*) 'Hello world!'</code> and <code>print *, 'Hello world!'</code></span>
|
||||
will compile to the exact same assembly. So if you only need to print something to stdout, just use <span><code>print *</code></span>
|
||||
as it conveys the meaning of the code better. Plus we don't need the full functionality of <span><code>write(*,*)</code></span>
|
||||
in this example.</p>
|
||||
With modern compilers, running the newest Fortran standards, <code-tag>write(*,*) 'Hello world!'</code-tag>
|
||||
and <code-tag>print *, 'Hello world!'</code-tag>
|
||||
will compile to the exact same assembly. So if you only need to print something to stdout, just use <code-tag>print *</code-tag>
|
||||
as it conveys the meaning of the code better. Plus we don't need the full functionality of <code-tag>write(*,*)</code-tag>
|
||||
in this example.</paragraph>
|
||||
|
||||
<div class="font-mono">
|
||||
<pre><code class="text-sm">
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ gfortran -o hello main.f90
|
||||
$ ./hello
|
||||
Hello world!
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<p>Now, hear me out, why not spice up the program a little bit more? What if we want to read user input? Well, fret
|
||||
<paragraph>Now, hear me out, why not spice up the program a little bit more? What if we want to read user input? Well, fret
|
||||
not my friend, because I have just the solution for you then. All we gotta do is to read from the terminal, and
|
||||
then print out the value.</p>
|
||||
then print out the value.</paragraph>
|
||||
|
||||
<div class="font-mono">
|
||||
<pre><code class="text-sm">
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
|
||||
@ -54,41 +58,37 @@ program hello
|
||||
print *, trim(usertxt)
|
||||
|
||||
end program hello
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<p>So what we're seeing here, is that we have created two variables: <span><code>usertxt</code> and <code>ios</code></span>.
|
||||
<span><code>usertxt</code></span> is the input we're reading from the terminal. Although since Fortran 90 doesn't
|
||||
have an explicit string type, doesn't mean we can't read or write text, as the <span><code>character</code></span>
|
||||
<paragraph>So what we're seeing here, is that we have created two variables: <code-tag>usertxt</code-tag>
|
||||
and <code-tag>ios</code-tag>.<code-tag>usertxt</code-tag> is the input we're reading from the terminal. Although since Fortran 90 doesn't
|
||||
have an explicit string type, doesn't mean we can't read or write text, as the <code-tag>character</code-tag>
|
||||
type is just an array of 1000 characters long. It doesn't have to be 1000 characters, but it's what I chose on a
|
||||
whim.</p>
|
||||
<br>
|
||||
whim.<br><br>
|
||||
|
||||
<p>The other variable, <span><code>ios</code></span>, I probably don't need to introduce, as it's just an integer.
|
||||
The other variable, <code-tag>ios</code-tag>, I probably don't need to introduce, as it's just an integer.
|
||||
But what control-flow this value holds, I feel is quite important, as a lot of file-based business logic makes
|
||||
use of it.</p>
|
||||
<br>
|
||||
use of it.<br><br>
|
||||
|
||||
<p>Introducing, <span><code>iostat</code></span>. AKA, Input/Output Status Specifier. It indicates the status of the
|
||||
Introducing, <code-tag>iostat</code-tag>. AKA, Input/Output Status Specifier. It indicates the status of the
|
||||
I/O operation. If the integer is positive, it indicates an error code. If it's negative, it indicates an end of file
|
||||
condition. If it's zero, then it does not indicate anything yet. No error, no End Of File, no particular condition
|
||||
has triggered yet.</p>
|
||||
<br>
|
||||
has triggered yet.<br><br>
|
||||
|
||||
<p>So in this case, where we check if <span><code>ios</code></span> is End Of File, then that means if we input an
|
||||
So in this case, where we check if <code-tag>ios</code-tag> is End Of File, then that means if we input an
|
||||
End Of File key combination (Ctrl+D on Unix/Linux, and Ctrl+Z on Windows), then the program would stop immediately.
|
||||
We use the <span><code>trim()</code></span> function to remove any trailing whitespaces. That's because, if you
|
||||
We use the <code-tag>trim()</code-tag> function to remove any trailing whitespaces. That's because, if you
|
||||
make a character array longer than the actual text, it will be filled with whitespace after the text. So now the output
|
||||
looks like this:</p>
|
||||
looks like this:</paragraph>
|
||||
|
||||
<div class="font-mono">
|
||||
<pre><code class="text-sm">
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ gfortran -o hello main.f90
|
||||
$ ./hello
|
||||
Input text here:
|
||||
Hello world :D
|
||||
Hello world :D
|
||||
</code></pre>
|
||||
</div>
|
||||
</code></pre>
|
||||
</div>
|
||||
</template>
|
@ -1,29 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl">Fortran</h1>
|
||||
<hr>
|
||||
<p>Fortran (Formula Translation), is one of the ancient languages somehow still in use as of today. First introduced
|
||||
<page-start>Fortran</page-start>
|
||||
|
||||
<paragraph>Fortran (Formula Translation), is one of the ancient languages somehow still in use as of today. First introduced
|
||||
in the 1950s by a team at IBM, Fortran was designed specifically for scientific and engineering applications,
|
||||
where its ability to efficiently handle complex mathematical operations far outperformed rivaling languages at the
|
||||
time.</p>
|
||||
<br>
|
||||
time.<br><br>
|
||||
|
||||
<p>
|
||||
Over the years, Fortran has undergone numerous updates and revisions, with the most recent standard being Fortran
|
||||
2023. Even with the popularity of newer languages, such as C++, Java, and Python, Fortran remains a popular choice
|
||||
in many fields, including physics, chemistry, meteorology, and engineering, due to its performance. Even Nvidia
|
||||
and Intel are still developing their compilers, as well as FOSS compilers such as gfortran and lfortran.</p>
|
||||
<br>
|
||||
and Intel are still developing their compilers, as well as FOSS compilers such as gfortran and lfortran.</paragraph>
|
||||
|
||||
<p>Table of contents:</p>
|
||||
<ul>
|
||||
<li><RouterLink to="/Fortran/SetUp">> Set Up</RouterLink></li>
|
||||
<li><RouterLink to="/Fortran/HelloWorld">> Hello World</RouterLink></li>
|
||||
<li><RouterLink to="/Fortran/DataTypes">> Data Types</RouterLink></li>
|
||||
<li><RouterLink to="/Fortran/Methods">> Method, Functions, Sub Routines and Calls</RouterLink></li>
|
||||
<li><RouterLink to="/Fortran/ReadingAFile">> Reading A File</RouterLink></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
@ -1,15 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl">Reading A File In Fortran 90</h1>
|
||||
<hr>
|
||||
<p></p>
|
||||
<page-start>Reading A File In Fortran 90</page-start>
|
||||
|
||||
<code class="">
|
||||
<paragraph>Reading files in high level programming languages is rather easy. In 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>
|
||||
</div>
|
||||
In Fortran 90, however, there is a little more than that. Not a lot more, to be honest, but there is a little more.
|
||||
Especially if you're using Fortran 90, compared to newer versions. In Fortran 90, you have to read the file, line
|
||||
by line.</paragraph>
|
||||
</template>
|
@ -1,93 +1,187 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import CodeTag from "../tags/CodeTag.vue";
|
||||
import PageStart from "../tags/PageStart.vue";
|
||||
import Paragraph from "../tags/Paragraph.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl">Setting Up The Environment</h1>
|
||||
<hr>
|
||||
<page-start>Setting Up The Environment</page-start>
|
||||
|
||||
<p>If you're familiar with C, then you would feel right at home with Fortran's build environment. There isn't really
|
||||
<paragraph>If you're familiar with C, then you would feel right at home with Fortran's build environment. There isn't really
|
||||
an "official" compiler for the language, only a standard, that has to be implemented by the compilers. But there
|
||||
are a lot of great compilers, that might as well be "official."</p>
|
||||
<br>
|
||||
are a lot of great compilers, that might as well be "official."<br><br>
|
||||
|
||||
<p>The top listed compiler on Fortran's website, is the GNU Fortran compiler (gfortran). It's the one I will be using
|
||||
The top listed compiler on Fortran's website, is the GNU Fortran compiler (gfortran). It's the one I will be using
|
||||
throughout the examples on the site. Unless stated otherwise. There are also some other notable compilers, that
|
||||
has some rather interesting qualities to them.</p>
|
||||
<br>
|
||||
has some rather interesting qualities to them.
|
||||
</paragraph>
|
||||
|
||||
<p>Compilers:</p>
|
||||
<ul>
|
||||
<ul class="mb-6">
|
||||
<li>> <a class="underline" href="https://lfortran.org/">lfortran</a> (This one can be used as an interactive
|
||||
compiler, supports parsing all of the 2018 standard syntax and also compile Fortran to WebAssemply).</li>
|
||||
<li>> <a class="underline" href="https://developer.nvidia.com/hpc-sdk">NVIDIA HPC SDK</a> (This one comes with a whole lot of GPU
|
||||
accelerated libraries).</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<p>But we will be using gfortran. Through the examples on this site, I will mainly be focusing on developing on Linux.</p>
|
||||
<br>
|
||||
<paragraph>But we will be using gfortran. Through the examples on this site, I will mainly be focusing on developing on Linux. <br>
|
||||
First, we install the compiler.
|
||||
</paragraph>
|
||||
|
||||
<p>First, we install the compiler.</p>
|
||||
<br>
|
||||
<p>For Fedora:</p>
|
||||
<code-tag>$ sudo dnf install gcc-gfortran</code-tag>
|
||||
|
||||
<p>For Fedora.</p>
|
||||
<code>$ sudo dnf install gcc-gfortran</code>
|
||||
<br>
|
||||
<br>
|
||||
<p>For ubuntu:</p>
|
||||
<code-tag>$ sudo apt install gfortran</code-tag>
|
||||
|
||||
<p>For ubuntu.</p>
|
||||
<code>$ sudo apt install gfortran</code>
|
||||
<br>
|
||||
<br>
|
||||
<paragraph>And that's it. Pretty easy.</paragraph>
|
||||
|
||||
<p>And that's it. Pretty easy.</p>
|
||||
<br>
|
||||
<h2 class="text-2xl">Project Structure</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<h1 class="text-3xl">Project Structure</h1>
|
||||
<hr>
|
||||
<paragraph>When creating a Fortran project, or any project in general, you want a structure. There is a lot of different
|
||||
layouts for the structure, but equal amongst them, is the <code-tag>src</code-tag> folder. That's where we keep all of out
|
||||
source code. Like <code-tag>*.f90, *.f95</code-tag> files.<br><br>
|
||||
|
||||
<p>When creating a Fortran project, or any project in general, you want a structure. There is a lot of different
|
||||
layouts for the structure, but equal amongst them, is the <code>src</code> folder. That's where we keep all of out
|
||||
source code. Like <code>*.f90, *.f95</code> files.</p>
|
||||
<br>
|
||||
|
||||
<p>But other than that, most projects include a <code>Makefile</code> file, a <code>library</code>, <code>test</code>
|
||||
and <code>bin</code> folder. Your layout doesn't need to look like this specifically, nor does it have to contain
|
||||
But other than that, most projects include a <code-tag>Makefile</code-tag> file, a
|
||||
<code-tag>library</code-tag>, <code-tag>test</code-tag>
|
||||
and <code-tag>bin</code-tag> folder. Your layout doesn't need to look like this specifically, nor does it have to contain
|
||||
the same folders. Each project is different, and so are the requirements. But this layout is simple, and great
|
||||
for medium to large projects.</p>
|
||||
<br>
|
||||
for medium to large projects.<br><br>
|
||||
|
||||
<p>But if we're doing micro-projects, as in like, a hello world application, a test application, or a small tool,
|
||||
But if we're doing micro-projects, as in like, a hello world application, a test application, or a small tool,
|
||||
this layout is rather redundant, and in the examples on this site, we will only use it on bigger projects,
|
||||
and we will let you know, when or how we set up the project.</p>
|
||||
<br>
|
||||
and we will let you know, when or how we set up the project.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono">
|
||||
<pre><code class="text-sm">
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
project/
|
||||
├── src/ # Source files (.f90, .f95, etc.)
|
||||
│ ├── modules/ # Module definitions
|
||||
│ └── main.f90 # Main program file
|
||||
├── include/ # Include files (e.g., interface definitions)
|
||||
├── include/ # Include files (interface definitions)
|
||||
├── lib/ # Library object files and archives
|
||||
├── bin/ # Executable binaries
|
||||
├── tests/ # Test cases
|
||||
├── tests/ # Test files
|
||||
└── Makefile # Build script
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<p>Notes:</p>
|
||||
<ul>
|
||||
<li>> <code>src</code> (This is where we keep all of out source code).</li>
|
||||
<li>> <code>modules</code> (This is where we keep our classes. Or in Fortran-speak, modules).</li>
|
||||
<li>> <code>include</code> (This is where we keep our interfaces, that out modules will inherit from, if we're using Fortran 90 or above).</li>
|
||||
<li>> <code>bin</code> (This is where the compiled program should end up in).</li>
|
||||
<ul class="mb-6">
|
||||
<li>> <code-tag>src</code-tag> (This is where we keep all of out source code).</li>
|
||||
<li>> <code-tag>modules</code-tag> (This is where we keep our classes. Or in Fortran-speak, modules).</li>
|
||||
<li>> <code-tag>include</code-tag> (This is where we keep our interfaces, that out modules will inherit from, if we're using Fortran 90 or above).</li>
|
||||
<li>> <code-tag>bin</code-tag> (This is where the compiled program should end up in).</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<p>Makefiles are very useful, and becomes increasingly useful, the bigger the project gets.</p> <!-- TODO: Continue from here. Show example. -->
|
||||
<h2 class="text-2xl">Compiling</h2>
|
||||
<hr class="mb-6">
|
||||
|
||||
<paragraph>Makefiles are very useful, and becomes increasingly useful, the bigger the project gets. A makefile simplifies the
|
||||
compilation process, as all of the compile flags can be gathered inside a single file. It makes it possible to
|
||||
dynamically change the compilation depending on the system architecture or config. It also removes the need to
|
||||
manually compile and link your objects together, every time you make a change.<br><br>
|
||||
|
||||
And with a bigger project, comes a big count of source files. That's where a makefile helps a lot, as it handles
|
||||
and tracks all changes to each file, ensuring that it's only the changed files that gets re-compiled.<br><br>
|
||||
|
||||
So let's see a makefile in action. Below code is a simple Hello World application, that we will use a makefile to
|
||||
compile. Although it's worth noting, that a program this small, a makefile is wildly redundant. But it does show
|
||||
how it's set up in a simple environment.
|
||||
</paragraph>
|
||||
|
||||
<code-tag>hello.f90</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
program hello
|
||||
implicit none
|
||||
print *, 'Hello, World!'
|
||||
end program hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<code-tag>Makefile</code-tag>
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
FC = gfortran # Fortran compiler
|
||||
FFLAGS = -O2 # Compiler flags (optimization level)
|
||||
|
||||
hello: hello.o
|
||||
$(FC) $(FFLAGS) -o $@ $^
|
||||
|
||||
hello.o: hello.f90
|
||||
$(FC) $(FFLAGS) -c $<
|
||||
|
||||
run:
|
||||
./hello
|
||||
|
||||
clean:
|
||||
rm -f *.o hello
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>
|
||||
The makefile, in the eyes of a modern programmer (C#, Python, JS, Etc) might look rather repulsive. But be not
|
||||
afraid, because at the end of the day, it's simply just some rules, that the compiler follows to compile your program.
|
||||
</paragraph>
|
||||
|
||||
<ul class="mb-6">
|
||||
<li>> <code-tag>hello: hello.o</code-tag></li>
|
||||
<li class="pb-2">> > Here, the program "hello" depends on the object file "hello.o".</li>
|
||||
|
||||
<li>> <code-tag>$(FC) $(FFLAGS) -o $@ $^</code-tag></li>
|
||||
<li class="pb-2">> > This one compiles the object files into the program.</li>
|
||||
|
||||
<li>> <code-tag>hello.o: hello.f90</code-tag></li>
|
||||
<li class="pb-2">> > Here, the object file "hello.o" depends on the source file "hello.f90".</li>
|
||||
|
||||
<li>> <code-tag>$(FC) $(FFLAGS) -c $<</code-tag></li>
|
||||
<li class="pb-2">> > This one compiles the source files into the object files.</li>
|
||||
|
||||
<li>> <code-tag>run: ./hello</code-tag></li>
|
||||
<li class="pb-2">> > This runs the program if you execute <code-tag>make run</code-tag></li>
|
||||
|
||||
<li>> <code-tag>clean: rm -f *.o hello</code-tag></li>
|
||||
<li class="pb-2">> > Here, the object files gets removed when running <code-tag>make clean</code-tag></li>
|
||||
</ul>
|
||||
|
||||
<paragraph>
|
||||
A quick note. It's very important that whenever something is indented in a makefile, that it's indented with a tab,
|
||||
and not 4 spaces. It needs to be a tab character.<br><br>
|
||||
|
||||
Now simply run the makefile with the following command.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ make
|
||||
gfortran -O2 -c hello.f90
|
||||
gfortran -O2 -o hello hello.o
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>
|
||||
We have now successfully compiled the program with the help of a makefile. Now simply run the program and we'll
|
||||
see the output.
|
||||
</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ ./hello
|
||||
Hello, World!
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<paragraph>The exact same should happen, if we run the next command instead.</paragraph>
|
||||
|
||||
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
||||
<pre><code class="text-sm">
|
||||
$ make run
|
||||
./hello
|
||||
Hello, World!
|
||||
</code></pre>
|
||||
</div>
|
||||
</template>
|
@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
3
src/components/tags/CodeTag.vue
Normal file
3
src/components/tags/CodeTag.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<code class="text-red-500"><slot/></code>
|
||||
</template>
|
4
src/components/tags/PageStart.vue
Normal file
4
src/components/tags/PageStart.vue
Normal file
@ -0,0 +1,4 @@
|
||||
<template>
|
||||
<h1 class="text-3xl"><slot></slot></h1>
|
||||
<hr class="mb-6">
|
||||
</template>
|
3
src/components/tags/Paragraph.vue
Normal file
3
src/components/tags/Paragraph.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<p class="mb-6"><slot></slot></p>
|
||||
</template>
|
20
src/main.ts
20
src/main.ts
@ -6,11 +6,13 @@ import App from './App.vue'
|
||||
import Home from "./components/Home.vue";
|
||||
import About from "./components/About.vue";
|
||||
import FortranIndex from "./components/Fortran/Fortran_Index.vue";
|
||||
import PascalIndex from "./components/Pascal/Pascal_Index.vue";
|
||||
import LispIndex from "./components/Lisp/Lisp_Index.vue";
|
||||
import FortranReadingFiles from "./components/Fortran/Fortran_Reading_Files.vue";
|
||||
import FortranHelloWorld from "./components/Fortran/Fortran_Hello_World.vue";
|
||||
import FortranSetUp from "./components/Fortran/Fortran_Set_Up.vue";
|
||||
import FortranDataTypes from "./components/Fortran/Fortran_Data_Types.vue";
|
||||
import FortranCallsMethodsFunctionsSubroutines from "./components/Fortran/Fortran_Calls_Methods_Functions_Subroutines.vue";
|
||||
import CIndex from "./components/C/C_Index.vue";
|
||||
import CSetUp from "./components/C/C_Set_Up.vue";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
@ -19,14 +21,14 @@ const router = createRouter({
|
||||
{path: '/About', name: 'About', component: About},
|
||||
|
||||
{path: '/Fortran', name: 'Fortran', component: FortranIndex},
|
||||
{path: '/Fortran/SetUp', name: 'SetUp', component: FortranSetUp},
|
||||
{path: '/Fortran/HelloWorld', name: 'HelloWorld', component: FortranHelloWorld},
|
||||
{path: '/Fortran/ReadingAFile', name: 'ReadingAFile', component: FortranReadingFiles},
|
||||
{path: '/Fortran/SetUp', name: 'F_SetUp', component: FortranSetUp},
|
||||
{path: '/Fortran/HelloWorld', name: 'F_HelloWorld', component: FortranHelloWorld},
|
||||
{path: '/Fortran/DataTypes', name: 'F_DataTypes', component: FortranDataTypes},
|
||||
{path: '/Fortran/Methods', name: 'F_Methods', component: FortranCallsMethodsFunctionsSubroutines},
|
||||
{path: '/Fortran/ReadingAFile', name: 'F_ReadingAFile', component: FortranReadingFiles},
|
||||
|
||||
{path: '/Pascal', name: 'Pascal', component: PascalIndex},
|
||||
|
||||
|
||||
{path: '/Lisp', name: 'Lisp', component: LispIndex}
|
||||
{path: '/C', name: 'C', component: CIndex},
|
||||
{path: '/C/SetUp', name: 'C_SetUp', component: CSetUp},
|
||||
]
|
||||
})
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
|
@ -1,20 +1,11 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
purge: [
|
||||
'./index.html',
|
||||
'./src/**/*.{vue,js,ts,jsx,tsx}'
|
||||
],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx,vue}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'ancient': '#d3d0c9',
|
||||
'ancient_highlight': '#fcf8f5',
|
||||
'ancient_shadow': '#bababa',
|
||||
},
|
||||
padding: {
|
||||
'small': '0.075rem',
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user