Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24,309 changes: 24,309 additions & 0 deletions Cuis/Powerlang.pck.st

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions modules/ArgParser/ArgParser.Class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
'From Cuis7.9 [latest update: #7998] on 28 June 2026 at 1:27:37 pm'!
!classDefinition: #ArgParser category: #ArgParser!
Object subclass: #ArgParser
instanceVariableNames: 'name description commands globalOptions'
classVariableNames: ''
poolDictionaries: ''
category: 'ArgParser'!
!ArgParser commentStamp: '<historical>' prior: 0!

Copyright (c) 2026, Javier Pimás.
See (MIT) license in root directory.
!

!ArgParser methodsFor: 'commands' stamp: 'KenD 28/Jun/2026 13:27:37'!
addCommand: aCommand
commands at: aCommand name put: aCommand
! !

!ArgParser methodsFor: 'options' stamp: 'KenD 28/Jun/2026 13:27:37'!
addGlobalOption: anOption
globalOptions add: anOption
! !

!ArgParser methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
description
^description
! !

!ArgParser methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
description: aString
description := aString
! !

!ArgParser methodsFor: 'parsing' stamp: 'KenD 28/Jun/2026 13:27:37'!
extractGlobalArgs: args
| remaining i |
remaining := OrderedCollection new.
i := 1.
[i <= args size] whileTrue: [
| arg match rest |
arg := args at: i.
match := globalOptions detect: [:opt | opt matches: arg] ifNone: [nil].
match ifNotNil: [
match hasValue ifTrue: [i := i + 1]
] ifNil: [
rest := args copyFrom: i to: args size.
^remaining addAll: rest; yourself].
i := i + 1].
^remaining
! !

!ArgParser methodsFor: 'initialization' stamp: 'KenD 28/Jun/2026 13:27:37'!
initialize
commands := OrderedDictionary new.
globalOptions := OrderedCollection new
! !

!ArgParser methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
name
^name
! !

!ArgParser methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
name: aString
name := aString
! !

!ArgParser methodsFor: 'parsing' stamp: 'KenD 28/Jun/2026 13:27:37'!
parse: args
| remaining key command result tail |
remaining := self extractGlobalArgs: args.
remaining isEmpty ifTrue: [self printHelp. ^nil].
key := remaining first.
command := commands at: key ifAbsent: [
self error: 'Unknown command: ', key, '. Run with no args for help.'].
result := ParseResult new.
result command: key.
tail := remaining copyFrom: 2 to: remaining size.
command parse: tail into: result.
command action ifNotNil: [:act | act value: result].
^result
! !

!ArgParser methodsFor: 'printing' stamp: 'KenD 28/Jun/2026 13:27:37'!
printHelp
| text |
text := name ifNil: ['command'].
description ifNotNil: [
text := text , ' - ' , description].
text := text , String cr , String cr , 'Commands:' , String cr.
commands keysAndValuesDo: [:key :cmd |
text := text , ' ' , key.
cmd description ifNotNil: [:d |
text := text , ' - ' , d].
text := text , String cr].
Kernel log: text
! !


"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

!classDefinition: 'ArgParser class' category: #ArgParser!
ArgParser class
instanceVariableNames: ''!


ArgParser initialize!

28 changes: 28 additions & 0 deletions modules/ArgParser/ArgParserModule.Class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'From Cuis7.9 [latest update: #7998] on 28 June 2026 at 1:27:37 pm'!
!classDefinition: #ArgParserModule category: #ArgParser!
Module subclass: #ArgParserModule
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'ArgParser'!
!ArgParserModule commentStamp: '<historical>' prior: 0!

Copyright (c) 2026, Javier Pimás.
See (MIT) license in root directory.
!

!ArgParserModule methodsFor: 'spec' stamp: 'KenD 28/Jun/2026 13:27:37'!
imports
^{
#Kernel -> #(Error OrderedDictionary).
}
! !


"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

!classDefinition: 'ArgParserModule class' category: #ArgParser!
ArgParserModule class
instanceVariableNames: ''!


163 changes: 163 additions & 0 deletions modules/ArgParser/Command.Class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
'From Cuis7.9 [latest update: #7998] on 28 June 2026 at 1:27:37 pm'!
!classDefinition: #Command category: #ArgParser!
Object subclass: #Command
instanceVariableNames: 'name description options positionalNames action subcommands'
classVariableNames: ''
poolDictionaries: ''
category: 'ArgParser'!
!Command commentStamp: '<historical>' prior: 0!

Copyright (c) 2026, Javier Pimás.
See (MIT) license in root directory.
!

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
action
^action
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
action: aBlock
action := aBlock
! !

!Command methodsFor: 'configuration' stamp: 'KenD 28/Jun/2026 13:27:37'!
addOption: anOption
options add: anOption
! !

!Command methodsFor: 'configuration' stamp: 'KenD 28/Jun/2026 13:27:37'!
addPositional: aString
positionalNames add: aString
! !

!Command methodsFor: 'configuration' stamp: 'KenD 28/Jun/2026 13:27:37'!
addSubcommand: aCommand
subcommands at: aCommand name put: aCommand
! !

!Command methodsFor: 'private' stamp: 'KenD 28/Jun/2026 13:27:37'!
applyDefaults: aResult
options do: [:opt |
(aResult hasOption: opt name) ifFalse: [
opt defaultValue ifNotNil: [:v |
aResult setOption: opt name to: v]]]
! !

!Command methodsFor: 'private' stamp: 'KenD 28/Jun/2026 13:27:37'!
checkRequired: aResult
options do: [:opt |
| name |
name := opt long ifNil: [opt short].
(opt required and: [(aResult hasOption: opt name) not])
ifTrue: [self error: 'Required option missing: ', name]]
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
description
^description
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
description: aString
description := aString
! !

!Command methodsFor: 'private' stamp: 'KenD 28/Jun/2026 13:27:37'!
findOption: aString
^options detect: [:opt | opt matches: aString] ifNone: [nil]
! !

!Command methodsFor: 'testing' stamp: 'KenD 28/Jun/2026 13:27:37'!
hasSubcommands
^subcommands notEmpty
! !

!Command methodsFor: 'initialization' stamp: 'KenD 28/Jun/2026 13:27:37'!
initialize
options := OrderedCollection new.
positionalNames := OrderedCollection new.
subcommands := OrderedDictionary new
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
name
^name
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
name: aString
name := aString
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
options
^options
! !

!Command methodsFor: 'parsing' stamp: 'KenD 28/Jun/2026 13:27:37'!
parse: args into: result
| i |
i := 1.
[i <= args size] whileTrue: [
| arg |
arg := args at: i.
(arg first = $-)
ifTrue: [i := self parseOption: arg from: args at: i into: result]
ifFalse: [result addPositional: arg].
i := i + 1].
self checkRequired: result.
self applyDefaults: result
! !

!Command methodsFor: 'parsing' stamp: 'KenD 28/Jun/2026 13:27:37'!
parseOption: aString from: anArray at: anInteger into: aResult
| opt |
opt := self findOption: aString.
opt ifNil: [self error: 'Unknown option: ', aString].
opt hasValue ifTrue: [
| val next |
next := anInteger + 1.
next > anArray size ifTrue: [self error: 'Option ', aString, ' requires a value'].
val := anArray at: next.
aResult setOption: opt name to: val.
^next]
ifFalse: [
aResult setOption: opt name to: true].
^anInteger
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
positionalNames
^positionalNames
! !

!Command methodsFor: 'printing' stamp: 'KenD 28/Jun/2026 13:27:37'!
printUsageOn: aStream
aStream nextPutAll: name.
positionalNames do: [:pname |
aStream nextPutAll: ' <'; nextPutAll: pname; nextPut: $>].
options do: [:opt |
aStream nextPutAll: ' ['.
opt short ifNotNil: [:s | aStream nextPutAll: s].
(opt short notNil and: [opt long notNil]) ifTrue: [aStream nextPutAll: '|'].
opt long ifNotNil: [:l | aStream nextPutAll: l].
opt hasValue ifTrue: [aStream nextPutAll: ' <value>'].
aStream nextPut: $]]
! !

!Command methodsFor: 'accessing' stamp: 'KenD 28/Jun/2026 13:27:37'!
subcommands
^subcommands
! !


"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

!classDefinition: 'Command class' category: #ArgParser!
Command class
instanceVariableNames: ''!


Command initialize!

Loading