a gleam implementation of a CS assignment originally written in cpp

Compare changes

Choose any two refs to compare.

+94 -12
README.md
···
-
# bible_search_gleam
-
[![Package Version](https://img.shields.io/hexpm/v/bible_search_gleam)](https://hex.pm/packages/bible_search_gleam)
-
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/bible_search_gleam/)
-
```sh
-
gleam add bible_search_gleam@1
-
```
```gleam
-
import bible_search_gleam
-
pub fn main() -> Nil {
-
// TODO: An example of the project in use
}
```
-
Further documentation can be found at <https://hexdocs.pm/bible_search_gleam>.
## Development
```sh
-
gleam run # Run the project
-
gleam test # Run the tests
```
···
+
# Lab 6 - Gleamified
+
[![Package Version](https://img.shields.io/hexpm/v/bible_search)](https://hex.pm/packages/bible_search)
+
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/bible_search/)
```gleam
+
pub fn bible_scan(
+
reference reference: Reference,
+
bible bible: String,
+
) -> ScanResult {
+
let inital_state =
+
ScanState(
+
phase: Book,
+
ref: reference,
+
found_book: False,
+
found_chapter: False,
+
verse_text: Error("Verse not found"),
+
)
+
+
let bible_lines = string.split(bible, "\n")
+
let result =
+
list.fold(bible_lines, inital_state, fn(state, line) -> ScanState {
+
case state.phase {
+
Done -> state
+
Book ->
+
case line {
+
"THE BOOK OF " <> book ->
+
case book == state.ref.book {
+
True -> ScanState(..state, phase: Chapter, found_book: True)
+
False -> state
+
}
+
_ -> state
+
}
+
Chapter ->
+
case line {
+
"CHAPTER " <> chapter ->
+
case result.unwrap(int.parse(chapter), 0) == state.ref.chapter {
+
True -> ScanState(..state, phase: Verse, found_chapter: True)
+
False -> state
+
}
+
_ -> state
+
}
+
Verse ->
+
fn() {
+
let parts = string.split(line, " ")
+
case parts {
+
[first, ..rest] ->
+
case result.unwrap(int.parse(first), 0) == state.ref.verse {
+
True ->
+
ScanState(
+
..state,
+
phase: Done,
+
verse_text: Ok(string.join(rest, " ")),
+
)
+
False -> state
+
}
+
_ -> state
+
}
+
}()
+
}
+
})
+
+
ScanResult(ref: reference, verse: result.verse_text)
}
```
+
For this lab the program must parse `OT.txt` (format below) to find specific references and produce scoped errors if the reference isn't found.
+
+
```text
+
THE BOOK OF GENESIS
+
+
CHAPTER 1
+
1 In the beginning God created the heaven and the earth.
+
2 And the earth was without form, and void; and darkness [was] upon the face of the deep. And the Spirit of God moved upon the face of the waters.
+
3 And God said, Let there be light: and there was light.
+
4 And God saw the light, that [it was] good: and God divided the light from the darkness.
+
+
THE BOOK OF PSALMS
+
+
PSALM 1
+
1 Blessed [is] the man that walketh not in the counsel of the ungodly, nor standeth in the way of sinners, nor sitteth in the seat of the scornful.
+
2 But his delight [is] in the law of the LORD; and in his law doth he meditate day and night.
+
3 And he shall be like a tree planted by the rivers of water, that bringeth forth his fruit in his season; his leaf also shall not wither; and whatsoever he doeth shall prosper.
+
```
## Development
+
+
You need to have the [gleam runtime](https://gleam.run/getting-started/installing/) installed as well as erlang for the beam runtime.
```sh
+
gleam run
+
gleam test # runs all the test functions in /tests postfixed with _test
```
+
+
<p align="center">
+
<img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/main/.github/images/line-break.svg" />
+
</p>
+
+
<p align="center">
+
<i><code>&copy 2025-present <a href="https://github.com/taciturnaxololt">Kieran Klukas</a></code></i>
+
</p>
+
+
<p align="center">
+
<a href="https://github.com/cu-cs1210/lab-6-kieranklukas/blob/main/LICENSE.md"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a>
+
</p>
+5 -11
gleam.toml
···
name = "bible_search"
-
version = "1.0.0"
-
# Fill out these fields if you intend to generate HTML documentation or publish
-
# your project to the Hex package manager.
-
#
-
# description = ""
-
# licences = ["Apache-2.0"]
-
# repository = { type = "github", user = "", repo = "" }
-
# links = [{ title = "Website", href = "" }]
-
#
-
# For a full reference of all the available options, you can have a look at
-
# https://gleam.run/writing-gleam/gleam-toml/.
[dependencies]
gleam_stdlib = ">= 0.44.0 and < 2.0.0"
···
name = "bible_search"
+
version = "0.1.0"
+
description = "search through the OT.txt bible format for a specific reference"
+
licences = ["MIT"]
+
repository = { type = "github", user = "cu-cs1210", repo = "lab-6-kieranklukas" }
+
links = [{ title = "Website", href = "https://dunkirk.sh" }]
[dependencies]
gleam_stdlib = ">= 0.44.0 and < 2.0.0"
+28 -15
src/bible_search.gleam
···
)
}
pub fn parse_reference(input: String) -> Result(Reference, String) {
let parts = string.split(input, on: " ")
···
}
}
-
pub fn main() -> Nil {
-
let assert Ok(bible) = simplifile.read(from: filepath)
-
-
let biblelines = string.split(bible, on: "\n")
-
-
let assert Ok(search) = input(prompt: "> ")
-
-
let assert Ok(reference) = parse_reference(search)
-
-
let inital =
ScanState(
phase: Book,
ref: reference,
···
verse_text: Error("Verse not found"),
)
let result =
-
list.fold(biblelines, inital, fn(state, line) -> ScanState {
case state.phase {
Done -> state
Book ->
···
}
})
-
case result.verse_text {
Ok(text) ->
io.println(
-
result.ref.book
<> " "
-
<> int.to_string(result.ref.chapter)
<> ":"
-
<> int.to_string(result.ref.verse)
<> " "
<> text,
)
···
)
}
+
pub type ScanResult {
+
ScanResult(ref: Reference, verse: Result(String, String))
+
}
+
pub fn parse_reference(input: String) -> Result(Reference, String) {
let parts = string.split(input, on: " ")
···
}
}
+
pub fn bible_scan(
+
reference reference: Reference,
+
bible bible: String,
+
) -> ScanResult {
+
let inital_state =
ScanState(
phase: Book,
ref: reference,
···
verse_text: Error("Verse not found"),
)
+
let bible_lines = string.split(bible, "\n")
+
let result =
+
list.fold(bible_lines, inital_state, fn(state, line) -> ScanState {
case state.phase {
Done -> state
Book ->
···
}
})
+
ScanResult(ref: reference, verse: result.verse_text)
+
}
+
+
pub fn main() -> Nil {
+
let assert Ok(bible) = simplifile.read(from: filepath)
+
+
let assert Ok(search) = input(prompt: "> ")
+
+
let assert Ok(reference) = parse_reference(search)
+
+
let scan = bible_scan(reference, bible)
+
+
case scan.verse {
Ok(text) ->
io.println(
+
scan.ref.book
<> " "
+
<> int.to_string(scan.ref.chapter)
<> ":"
+
<> int.to_string(scan.ref.verse)
<> " "
<> text,
)
+99 -7
test/bible_search_test.gleam
···
import bible_search
import gleeunit
pub fn main() -> Nil {
gleeunit.main()
···
// gleeunit test functions end in `_test`
pub fn parse_reference_test() {
let ref = bible_search.parse_reference("FIRST KINGS 10 10")
let expected_ref =
Ok(bible_search.Reference(book: "FIRST KINGS", chapter: 10, verse: 10))
-
assert Ok(ref) == Ok(expected_ref)
}
pub fn parse_reference_single_word_book_test() {
let ref = bible_search.parse_reference("GENESIS 1 1")
let expected_ref =
Ok(bible_search.Reference(book: "GENESIS", chapter: 1, verse: 1))
-
assert Ok(ref) == Ok(expected_ref)
}
pub fn parse_reference_invalid_chapter_test() {
let ref = bible_search.parse_reference("GENESIS abc 1")
let expected_error = Error("Invalid chapter: abc")
-
assert ref == expected_error
}
pub fn parse_reference_invalid_verse_test() {
let ref = bible_search.parse_reference("GENESIS 1 xyz")
let expected_error = Error("Invalid verse: xyz")
-
assert ref == expected_error
}
pub fn parse_reference_too_few_parts_test() {
let ref = bible_search.parse_reference("GENESIS 1")
let expected_error = Error("invalid parse")
-
assert ref == expected_error
}
pub fn parse_reference_too_many_parts_test() {
let ref = bible_search.parse_reference("SONG OF SOLOMON 1 1")
let expected_error = Error("invalid parse")
-
assert ref == expected_error
}
pub fn parse_reference_lowercase_book_test() {
let ref = bible_search.parse_reference("genesis 1 1")
let expected_ref =
Ok(bible_search.Reference(book: "GENESIS", chapter: 1, verse: 1))
-
assert Ok(ref) == Ok(expected_ref)
}
···
import bible_search
import gleeunit
+
import gleeunit/should
pub fn main() -> Nil {
gleeunit.main()
···
// gleeunit test functions end in `_test`
pub fn parse_reference_test() {
let ref = bible_search.parse_reference("FIRST KINGS 10 10")
+
should.be_ok(ref)
+
let expected_ref =
Ok(bible_search.Reference(book: "FIRST KINGS", chapter: 10, verse: 10))
+
should.be_true(ref == expected_ref)
}
pub fn parse_reference_single_word_book_test() {
let ref = bible_search.parse_reference("GENESIS 1 1")
+
should.be_ok(ref)
+
let expected_ref =
Ok(bible_search.Reference(book: "GENESIS", chapter: 1, verse: 1))
+
should.be_true(ref == expected_ref)
}
pub fn parse_reference_invalid_chapter_test() {
let ref = bible_search.parse_reference("GENESIS abc 1")
+
should.be_error(ref)
+
let expected_error = Error("Invalid chapter: abc")
+
should.be_true(ref == expected_error)
}
pub fn parse_reference_invalid_verse_test() {
let ref = bible_search.parse_reference("GENESIS 1 xyz")
+
should.be_error(ref)
let expected_error = Error("Invalid verse: xyz")
+
should.be_true(ref == expected_error)
}
pub fn parse_reference_too_few_parts_test() {
let ref = bible_search.parse_reference("GENESIS 1")
+
should.be_error(ref)
let expected_error = Error("invalid parse")
+
should.be_true(ref == expected_error)
}
pub fn parse_reference_too_many_parts_test() {
let ref = bible_search.parse_reference("SONG OF SOLOMON 1 1")
+
should.be_error(ref)
let expected_error = Error("invalid parse")
+
should.be_true(ref == expected_error)
}
pub fn parse_reference_lowercase_book_test() {
let ref = bible_search.parse_reference("genesis 1 1")
+
should.be_ok(ref)
+
let expected_ref =
Ok(bible_search.Reference(book: "GENESIS", chapter: 1, verse: 1))
+
should.be_true(ref == expected_ref)
+
}
+
+
pub fn bible_scan_found_verse_test() {
+
let bible =
+
"THE BOOK OF GENESIS
+
+
CHAPTER 1
+
+
1 In the beginning God created the heaven and the earth.
+
2 And the earth was without form, and void; and darkness was upon the face of the deep."
+
+
let ref = bible_search.Reference(book: "GENESIS", chapter: 1, verse: 1)
+
let result = bible_search.bible_scan(reference: ref, bible: bible)
+
+
should.be_true(
+
result.verse == Ok("In the beginning God created the heaven and the earth."),
+
)
+
}
+
+
pub fn bible_scan_verse_not_found_test() {
+
let bible =
+
"THE BOOK OF GENESIS
+
+
CHAPTER 1
+
+
1 In the beginning God created the heaven and the earth."
+
+
let ref = bible_search.Reference(book: "GENESIS", chapter: 1, verse: 99)
+
let result = bible_search.bible_scan(reference: ref, bible: bible)
+
+
should.be_true(result.verse == Error("Verse not found"))
+
}
+
+
pub fn bible_scan_book_not_found_test() {
+
let bible =
+
"THE BOOK OF GENESIS
+
+
CHAPTER 1
+
+
1 In the beginning God created the heaven and the earth."
+
+
let ref = bible_search.Reference(book: "EXODUS", chapter: 1, verse: 1)
+
let result = bible_search.bible_scan(reference: ref, bible: bible)
+
+
should.be_true(result.verse == Error("Verse not found"))
+
}
+
+
pub fn bible_scan_chapter_not_found_test() {
+
let bible =
+
"THE BOOK OF GENESIS
+
+
CHAPTER 1
+
+
1 In the beginning God created the heaven and the earth."
+
+
let ref = bible_search.Reference(book: "GENESIS", chapter: 99, verse: 1)
+
let result = bible_search.bible_scan(reference: ref, bible: bible)
+
+
should.be_true(result.verse == Error("Verse not found"))
+
}
+
+
pub fn bible_scan_multiple_verses_test() {
+
let bible =
+
"THE BOOK OF GENESIS
+
+
CHAPTER 1
+
+
1 In the beginning God created the heaven and the earth.
+
2 And the earth was without form, and void; and darkness was upon the face of the deep.
+
3 And God said, Let there be light: and there was light."
+
+
let ref = bible_search.Reference(book: "GENESIS", chapter: 1, verse: 2)
+
let result = bible_search.bible_scan(reference: ref, bible: bible)
+
+
should.be_true(
+
result.verse
+
== Ok(
+
"And the earth was without form, and void; and darkness was upon the face of the deep.",
+
),
+
)
}