Skip to content

Commit ae885b2

Browse files
committed
Init
0 parents  commit ae885b2

39 files changed

Lines changed: 1968 additions & 0 deletions

.github/workflows/TagBot.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: TagBot
2+
on:
3+
issue_comment:
4+
types:
5+
- created
6+
workflow_dispatch:
7+
inputs:
8+
lookback:
9+
default: 3
10+
permissions:
11+
actions: read
12+
checks: read
13+
contents: write
14+
deployments: read
15+
issues: read
16+
discussions: read
17+
packages: read
18+
pages: read
19+
pull-requests: read
20+
repository-projects: read
21+
security-events: read
22+
statuses: read
23+
jobs:
24+
TagBot:
25+
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: JuliaRegistries/TagBot@v1
29+
with:
30+
token: ${{ secrets.GITHUB_TOKEN }}
31+
# Edit the following line to reflect the actual name of the GitHub Secret containing your private key
32+
ssh: ${{ secrets.DOCUMENTER_KEY }}
33+
# ssh: ${{ secrets.NAME_OF_MY_SSH_PRIVATE_KEY_SECRET }}

.github/workflows/test.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Run JuliaObjectSystem tests
2+
3+
# Controls when the workflow will run
4+
on:
5+
# Triggers the workflow on push or pull request events but only for the "main" branch
6+
push:
7+
branches: [ "main" ]
8+
pull_request:
9+
branches: [ "main" ]
10+
11+
# Allows you to run this workflow manually from the Actions tab
12+
workflow_dispatch:
13+
14+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
15+
jobs:
16+
test:
17+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
18+
runs-on: ${{ matrix.os }}
19+
strategy:
20+
matrix:
21+
version:
22+
- "1" # Latest Release
23+
arch:
24+
- x64
25+
- x86
26+
os: [ubuntu-latest, macOS-latest, windows-latest]
27+
exclude:
28+
# Test 32-bit only on Linux
29+
- os: macOS-latest
30+
arch: x86
31+
- os: windows-latest
32+
arch: x86
33+
34+
steps:
35+
- uses: actions/checkout@v3
36+
- uses: julia-actions/setup-julia@v1
37+
with:
38+
version: ${{ matrix.version }}
39+
arch: ${{ matrix.arch }}
40+
- uses: julia-actions/julia-buildpkg@latest
41+
- uses: julia-actions/julia-runtest@latest
42+
with:
43+
annotate: true
44+

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#vscode
2+
.vscode/
3+
4+
# Files generated by invoking Julia with --code-coverage
5+
*.jl.cov
6+
*.jl.*.cov
7+
8+
# Files generated by invoking Julia with --track-allocation
9+
*.jl.mem
10+
11+
# System-specific files and directories generated by the BinaryProvider and BinDeps packages
12+
# They contain absolute paths specific to the host computer, and so should not be committed
13+
deps/deps.jl
14+
deps/build.log
15+
deps/downloads/
16+
deps/usr/
17+
deps/src/
18+
19+
# Build artifacts for creating documentation generated by the Documenter package
20+
docs/build/
21+
docs/site/
22+
23+
# File generated by Pkg, the package manager, based on a corresponding Project.toml
24+
# It records a fixed state of all packages used by the project. As such, it should not be
25+
# committed for packages, but should be committed for applications that require a static
26+
# environment.
27+
Manifest.toml

Development.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Development of Julia Object System
2+
3+
A Document to register features that I still need to implement, plus, if I need to, logs for my development logic
4+
5+
## What needs doing
6+
7+
- [x] 2.0 Macros
8+
- [x] 2.0.1 defclass
9+
- [x] 2.0.2 defgeneric
10+
- [x] 2.0.3 defmethod
11+
- [x] 2.0.4 defbuiltin
12+
- [x] 2.1 Classes
13+
- [x] 2.2 Instances
14+
- [x] 2.3 Slot Access
15+
- [x] 2.4 Generic Functions and methods
16+
- [x] 2.5 Pre-defined Generic Functions and Methods
17+
- [x] 2.6 MetaObjects
18+
- [x] 2.7 Class Options
19+
- [x] 2.8 Readers and Writers
20+
- [x] 2.9 Generic Function Calls
21+
- [x] 2.10 Multiple Dispatch
22+
- [x] 2.11 Multiple Inheritance
23+
- [x] 2.12 Class Hierarchy
24+
- [x] 2.13 Class Precedence List
25+
- [x] 2.14 Built-In Classes
26+
- [x] 2.15 Introspection
27+
- [x] 2.16 Meta-Object Protocols
28+
- [x] 2.16.1 Class Instantiation Protocol
29+
- [x] 2.16.2 The Compute Slots Protocol
30+
- [x] 2.16.3 Slot Access Protocol
31+
- [x] 2.16.4 Class Precedence List protocol
32+
- [x] 2.17 Multiple Meta-Class Inheritance
33+
- [ ] 2.18 Extensions
34+
- [ ] 2.18.1 Meta-Objects for slot definitions
35+
- [ ] 2.18.2 CLOS-like method combination for generic functions
36+
- [ ] 2.18.3 CLOS or Dylan's strategy for computing the class precedence list
37+
- [ ] 2.18.4 Additional Metaobject protocols
38+
- [x] Make `check_polymorphism` and `check_class` a JOS method
39+
- [x] Make `is_class`
40+
- [x] Make `non-applicable-method` predefined
41+
- [x] If generic function does not exist when method created, auto generate it
42+
- [x] Compute class precedence list
43+
- [x] Compute slots
44+
- [x] Refactor so that defclass uses instantiation protocol
45+
- [x] Refactor so that defgeneric uses instantiation protocol
46+
- [x] Refactor so that defmethod uses instantiation protocol
47+
- [ ] Add support for unions
48+
- [ ] Add call previous method
49+
- [ ] Improve how comparisons between slots is made so that I dont need to override hash
50+
- [ ] Check and Improve introspection assertions
51+
- [ ] Ability to call new without naming properties (in order?)
52+
- [ ] Create a Julia library?
53+
- [ ] Replace `getfield(o, :class_of_reference)` with `class_of(o)`
54+
- [ ] Solve warning on running tests "Warning: Assignment to `Person` in soft scope is ambiguous because a global variable by the same name exists: `Person` will be treated as a new local. Disambiguate by using `local Person` to suppress this warning or `global Person` to assign to the existing global variable."
55+
- [ ] Update branch protection
56+
- [ ] Uniformize naming conventions

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Eduardo Barrancos
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Project.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name = "ObjectSystem"
2+
uuid = "beb21ac1-5488-4e8e-a65a-eed5c6ff7e13"
3+
authors = ["Eduardo Barrancos <eduardobarrancos11488@gmail.com>"]
4+
version = "1.0.0"
5+
6+
[extras]
7+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
8+
9+
[compat]
10+
julia = "1"
11+
12+
[targets]
13+
test = ["Test"]

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Julia-Object-System
2+
3+
JOS (Julia Object System) is an extension to the Julia Programming language that supports classes and meta-classes, multiple inheritance and generic functions with multiple-dispatch methods.
4+
5+
## Description
6+
7+
This project was first developed for the course of [*Advanced Programming*](https://fenix.tecnico.ulisboa.pt/disciplinas/PAva/2022-2023/2-semestre) by:
8+
9+
- Eduardo Barrancos
10+
- Juliana Yang
11+
- Miguel Faria
12+
- Xin Zheng
13+
14+
Currently the project is being further developed, fixing some issues and adding additional features by:
15+
16+
- Eduardo Barrancos

src/Data/BaseJOS.jl

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
export BaseStructure, SlotDefinition,
2+
Top, Object, Class, BuiltInClass
3+
4+
mutable struct BaseStructure
5+
class_of_reference::Any #= Supposed to be another BaseStructure =#
6+
slots::Dict{Symbol, Any}
7+
end
8+
9+
mutable struct SlotDefinition
10+
name::Symbol
11+
initform::Any
12+
end
13+
14+
mutable struct SlotValue
15+
value::Any
16+
getter::Any
17+
setter::Any
18+
end
19+
20+
function Base.hash(one::SlotDefinition)
21+
return hash(one.name)
22+
end
23+
24+
function Base.:(==)(one::SlotDefinition, another::SlotDefinition)
25+
return one.name == another.name
26+
end
27+
28+
function Base.:(==)(one::Symbol, another::SlotDefinition)
29+
return one == another.name
30+
end
31+
32+
function Base.:(==)(one::SlotDefinition, another::Symbol)
33+
return one.name == another
34+
end
35+
36+
function slot_value_factory(slot_name::Symbol, slot_value)
37+
return SlotValue(
38+
slot_value,
39+
(instance) -> getfield(instance, :slots)[slot_name].value,
40+
(instance, new_value) -> getfield(instance, :slots)[slot_name].value = new_value
41+
)
42+
end
43+
44+
Top = BaseStructure(
45+
nothing,
46+
Dict(
47+
:name=>slot_value_factory(:name, :Top),
48+
:direct_superclasses=>slot_value_factory(:direct_superclasses, []),
49+
:direct_slots=>slot_value_factory(:direct_slots, []),
50+
:class_precedence_list=>slot_value_factory(:class_precedence_list, []),
51+
:slots=>slot_value_factory(:slots, []),
52+
)
53+
)
54+
55+
pushfirst!(getfield(Top, :slots)[:class_precedence_list].value, Top)
56+
57+
Object = BaseStructure(
58+
nothing,
59+
Dict(
60+
:name=>slot_value_factory(:name, :Object),
61+
:direct_superclasses=>slot_value_factory(:direct_superclasses, [Top]),
62+
:direct_slots=>slot_value_factory(:direct_slots, []),
63+
:class_precedence_list=>slot_value_factory(:class_precedence_list, [Top]),
64+
:slots=>slot_value_factory(:slots, []),
65+
)
66+
)
67+
68+
pushfirst!(getfield(Object, :slots)[:class_precedence_list].value, Object)
69+
70+
Class = BaseStructure(
71+
nothing,
72+
Dict(
73+
:name => slot_value_factory(:name, :Class),
74+
:direct_superclasses => slot_value_factory(:direct_superclasses, [Object]),
75+
:direct_slots => slot_value_factory(:direct_slots, [
76+
SlotDefinition(:name, missing),
77+
SlotDefinition(:direct_superclasses, []),
78+
SlotDefinition(:class_precedence_list, []),
79+
SlotDefinition(:direct_slots, []),
80+
SlotDefinition(:slots, [])]),
81+
:class_precedence_list => slot_value_factory(:class_precedence_list, [Object, Top]),
82+
:slots => slot_value_factory(:slots, [
83+
SlotDefinition(:name, missing),
84+
SlotDefinition(:direct_superclasses, []),
85+
SlotDefinition(:class_precedence_list, []),
86+
SlotDefinition(:direct_slots, []),
87+
SlotDefinition(:slots, [])])
88+
)
89+
)
90+
91+
pushfirst!(getfield(Class, :slots)[:class_precedence_list].value, Class)
92+
93+
setfield!(Class, :class_of_reference, Class)
94+
setfield!(Object, :class_of_reference, Class)
95+
setfield!(Top, :class_of_reference, Class)
96+
97+
BuiltInClass = BaseStructure(
98+
Class,
99+
Dict(
100+
:name => slot_value_factory(:name, :BuiltInClass),
101+
:direct_superclasses => slot_value_factory(:direct_superclasses, [Class]),
102+
:direct_slots => slot_value_factory(:direct_slots, []),
103+
:class_precedence_list => slot_value_factory(:class_precedence_list, [Class]),
104+
:slots => slot_value_factory(:slots, [
105+
SlotDefinition(:name, missing),
106+
SlotDefinition(:direct_superclasses, []),
107+
SlotDefinition(:class_precedence_list, []),
108+
SlotDefinition(:direct_slots, []),
109+
SlotDefinition(:slots, [])])
110+
)
111+
)
112+
113+
pushfirst!(getfield(BuiltInClass, :slots)[:class_precedence_list].value, BuiltInClass)
114+
115+
function Base.getproperty(obj::BaseStructure, sym::Symbol)
116+
getfield(obj, :slots)[sym].getter(obj)
117+
end
118+
119+
function Base.setproperty!(obj::BaseStructure, sym::Symbol, value)
120+
getfield(obj, :slots)[sym].setter(obj, value)
121+
end

0 commit comments

Comments
 (0)