aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2023-03-08 13:47:16 +0000
committerPaulo Custodio <pauloscustodio@gmail.com>2023-03-08 13:47:16 +0000
commitf904ee6db63dee40cdf1a0ea8ee1ec54403049a2 (patch)
tree48f307795861485837a4187f57e73f17d24fb998
parentbfe70d7565bca8008bd14f7f8260924cefe8e8b1 (diff)
downloadperlweeklychallenge-club-f904ee6db63dee40cdf1a0ea8ee1ec54403049a2.tar.gz
perlweeklychallenge-club-f904ee6db63dee40cdf1a0ea8ee1ec54403049a2.tar.bz2
perlweeklychallenge-club-f904ee6db63dee40cdf1a0ea8ee1ec54403049a2.zip
Add Forth solution
-rw-r--r--challenge-203/paulo-custodio/forth/ch-1.fs2
-rw-r--r--challenge-203/paulo-custodio/forth/ch-2.fs114
2 files changed, 116 insertions, 0 deletions
diff --git a/challenge-203/paulo-custodio/forth/ch-1.fs b/challenge-203/paulo-custodio/forth/ch-1.fs
index 7e8f128fb8..1e91b0e685 100644
--- a/challenge-203/paulo-custodio/forth/ch-1.fs
+++ b/challenge-203/paulo-custodio/forth/ch-1.fs
@@ -1,3 +1,5 @@
+#! /usr/bin/env gforth
+
\ Challenge 203
\
\ Task 1: Special Quadruplets
diff --git a/challenge-203/paulo-custodio/forth/ch-2.fs b/challenge-203/paulo-custodio/forth/ch-2.fs
new file mode 100644
index 0000000000..d5a78799b1
--- /dev/null
+++ b/challenge-203/paulo-custodio/forth/ch-2.fs
@@ -0,0 +1,114 @@
+#! /usr/bin/env gforth
+
+\ Challenge 203
+\
+\ Task 2: Copy Directory
+\ Submitted by: Julien Fiegehenn
+\
+\ You are given path to two folders, $source and $target.
+\
+\ Write a script that recursively copy the directory from $source to $target
+\ except any files.
+\
+\ Example
+\
+\ Input: $source = '/a/b/c' and $target = '/x/y'
+\
+\ Source directory structure:
+\
+\ ├── a
+\ │ └── b
+\ │ └── c
+\ │ ├── 1
+\ │ │ └── 1.txt
+\ │ ├── 2
+\ │ │ └── 2.txt
+\ │ ├── 3
+\ │ │ └── 3.txt
+\ │ ├── 4
+\ │ └── 5
+\ │ └── 5.txt
+\
+\ Target directory structure:
+\
+\ ├── x
+\ │ └── y
+\
+\ Expected Result:
+\
+\ ├── x
+\ │ └── y
+\ | ├── 1
+\ │ ├── 2
+\ │ ├── 3
+\ │ ├── 4
+\ │ └── 5
+
+\ copy text to counted string
+: copy_text { addr-from len addr-to -- }
+ addr-from addr-to 1+ len CMOVE
+ len addr-to C!
+;
+
+\ append text to counted string
+: cat_text { addr-cstr addr-from len-from -- }
+ addr-from addr-cstr COUNT + len-from CMOVE
+ addr-cstr C@ len-from + addr-cstr C!
+;
+
+\ concat two paths
+: cat_paths { target addr-path1 len-path1 addr-path2 len-path2 -- }
+ 0 target C!
+ target addr-path1 len-path1 cat_text
+ target S" /" cat_text
+ target addr-path2 len-path2 cat_text
+;
+
+: is_dot_dot_dot { cstr -- f }
+ cstr COUNT S" ." COMPARE 0=
+ cstr COUNT S" .." COMPARE 0= OR
+;
+
+: is_dir { cstr -- f }
+ cstr COUNT OPEN-DIR 0= IF \ ok
+ CLOSE-DIR THROW
+ TRUE
+ ELSE
+ DROP
+ FALSE
+ THEN
+;
+
+\ copy dirs
+: copy_dirs { source-addr target-addr -- }
+ source-addr COUNT OPEN-DIR THROW { dirid }
+ 256 ALLOCATE THROW { fname }
+ BEGIN fname 1+ 255 dirid READ-DIR THROW WHILE
+ fname C!
+ fname is_dot_dot_dot 0= IF
+ 256 ALLOCATE THROW { source-file }
+ source-file source-addr COUNT fname COUNT cat_paths
+
+ 256 ALLOCATE THROW { target-file }
+ target-file target-addr COUNT fname COUNT cat_paths
+
+ source-file is_dir IF
+ target-file COUNT [ 8 BASE ! 777 DECIMAL ] LITERAL
+ MKDIR-PARENTS THROW
+ THEN
+
+ source-file FREE THROW
+ target-file FREE THROW
+ THEN
+ REPEAT
+ fname FREE THROW
+;
+
+\ file names
+CREATE source_dir 256 ALLOT
+CREATE target_dir 256 ALLOT
+
+NEXT-ARG DUP 0= THROW source_dir copy_text
+NEXT-ARG DUP 0= THROW target_dir copy_text
+source_dir target_dir copy_dirs
+BYE