├── .gitattributes
├── .idea
└── .idea.Sunset
│ └── .idea
│ ├── .gitignore
│ ├── encodings.xml
│ ├── indexLayout.xml
│ └── vcs.xml
├── Assembly logic
├── Array logic.asm
├── Classes and structs.asm
├── Foreach loops logic.asm
├── Functions, local vars, parameters logic.asm
├── If statements logic.asm
├── Multi foreach logic.asm
├── Stack instruction execution.asm
├── String logic.asm
├── While loops logic.asm
├── datasect_test.ASM
└── datasect_test.EXE
├── LICENSE
├── README.md
├── Sunset.sln
└── Sunset
├── ArrayStyle.cs
├── Block.cs
├── Class.cs
├── ClassType.cs
├── CompileType.cs
├── Executor.cs
├── FunctionType.cs
├── Keywords
├── KWAcknowledge.cs
├── KWAs.cs
├── KWBecomes.cs
├── KWBoolean.cs
├── KWBreak.cs
├── KWByte.cs
├── KWByteSizeOf.cs
├── KWCallptr.cs
├── KWCase.cs
├── KWCast.cs
├── KWConstant.cs
├── KWConstructor.cs
├── KWContinue.cs
├── KWCrash.cs
├── KWDecrease.cs
├── KWDefault.cs
├── KWDllReference.cs
├── KWElse.cs
├── KWEnum.cs
├── KWExit.cs
├── KWExpectedTypes.cs
├── KWFinishCompiling.cs
├── KWForeach.cs
├── KWFunction.cs
├── KWGetProcessHeap.cs
├── KWGoto.cs
├── KWIf.cs
├── KWImport.cs
├── KWIncrease.cs
├── KWInherit.cs
├── KWInteger.cs
├── KWLengthOf.cs
├── KWLocal.cs
├── KWMultiForeach.cs
├── KWNew.cs
├── KWNofunc.cs
├── KWPrivate.cs
├── KWPublic.cs
├── KWPullable.cs
├── KWReturn.cs
├── KWSetOrigin.cs
├── KWSetProcessHeapVar.cs
├── KWSetStyle.cs
├── KWShort.cs
├── KWSizeOf.cs
├── KWStatic.cs
├── KWString.cs
├── KWStruct.cs
├── KWSwitch.cs
├── KWToggleGui.cs
├── KWTypeSizeOf.cs
├── KWVoid.cs
├── KWWhile.cs
├── Keyword.cs
├── KeywordMgr.cs
├── KeywordResult.cs
└── KeywordType.cs
├── Machine.cs
├── Modifier.cs
├── OpcodeIndexReference.cs
├── OpcodeIndexType.cs
├── Order.cs
├── PEHeader.cs
├── Parser.cs
├── ParsingError.cs
├── ParsingStatus.cs
├── Program.cs
├── Properties
└── AssemblyInfo.cs
├── Stack
├── EsiPtr.cs
├── IPseudoStackItem.cs
├── ItemType.cs
├── LocalVar.cs
├── PreservedEBP.cs
├── PreservedECX.cs
├── PseudoStack.cs
├── ReturnPtr.cs
└── SwitchVar.cs
├── Sunset.cd
├── Sunset.csproj
├── Sunset.sln
├── SunsetProject.cs
├── VarType.cs
├── VarTypes
└── Function.cs
├── app.config
├── bin
├── Debug
│ ├── ASCIIKey.sunset
│ ├── Capture.PNG
│ ├── Color.sunset
│ ├── Dictionary.sunset
│ ├── Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)
│ │ ├── Acknowledge Keyword.txt
│ │ ├── Callptr keyword.txt
│ │ ├── Constructor Demo
│ │ │ ├── MyClass.sunset
│ │ │ └── source.txt
│ │ ├── Dll Referencing.txt
│ │ ├── Docs.sunset
│ │ ├── Exit.txt
│ │ ├── Foreach loops.txt
│ │ ├── Form Demo
│ │ │ └── source.txt
│ │ ├── In-line Math Test Source.txt
│ │ ├── Initialize array from many values.txt
│ │ ├── Integer to Byte Demo
│ │ │ └── source.txt
│ │ ├── Labels and Goto.txt
│ │ ├── List Demo
│ │ │ └── source.txt
│ │ ├── Modifiers
│ │ │ ├── MyClass.sunset
│ │ │ ├── Test
│ │ │ │ └── TestClass.sunset
│ │ │ └── source.txt
│ │ ├── Multi Foreach.txt
│ │ ├── Passing Acknowledgements Demo
│ │ │ ├── MyClass.sunset
│ │ │ └── source.txt
│ │ ├── Passing Var Types into Class Demo
│ │ │ ├── MyClass.sunset
│ │ │ ├── OtherClass.sunset
│ │ │ └── source.txt
│ │ ├── Simple Forms Game
│ │ │ └── source.txt
│ │ ├── Struct Demo
│ │ │ ├── MSG.sunset
│ │ │ ├── PAINTSTRUCT.sunset
│ │ │ ├── POINT.sunset
│ │ │ ├── RECT.sunset
│ │ │ ├── WNDCLASSA.sunset
│ │ │ └── source.txt
│ │ ├── Switch, Case and Default.txt
│ │ ├── While Loops.txt
│ │ └── lengthof, sizeof and Tsizeof.txt
│ ├── Event.sunset
│ ├── ImageReference.sunset
│ ├── Important
│ │ └── DemoProject.sunset
│ ├── List.sunset
│ ├── Math.sunset
│ ├── Numbers.sunset
│ ├── Random.sunset
│ ├── String.sunset
│ ├── Sunset.exe
│ ├── Sunset.exe.config
│ ├── Sunset.pdb
│ ├── Sunset_Syntax.esy
│ ├── Todo list.txt
│ ├── Tuple.sunset
│ ├── Windows
│ │ ├── CollisionEventArgs.sunset
│ │ ├── Components
│ │ │ ├── Button.sunset
│ │ │ ├── Component.sunset
│ │ │ ├── Ellipse.sunset
│ │ │ ├── FormImage.sunset
│ │ │ ├── ListBox.sunset
│ │ │ ├── ListBoxEntry.sunset
│ │ │ ├── ProgressBar.sunset
│ │ │ ├── Rectangle.sunset
│ │ │ ├── RoundRectangle.sunset
│ │ │ ├── SimpleLabel.sunset
│ │ │ └── TreeView.sunset
│ │ ├── Drawing
│ │ │ ├── BITMAP.sunset
│ │ │ ├── ImageUtil.sunset
│ │ │ ├── Line.sunset
│ │ │ ├── PAINTSTRUCT.sunset
│ │ │ ├── POINT.sunset
│ │ │ ├── RECT.sunset
│ │ │ ├── RECTF.sunset
│ │ │ ├── SIZE.sunset
│ │ │ └── Shapes.sunset
│ │ ├── ErrorHandler.sunset
│ │ ├── Form.sunset
│ │ ├── FormEventArgs.sunset
│ │ ├── FormTimer.sunset
│ │ ├── GUID.sunset
│ │ ├── KeyEventArgs.sunset
│ │ ├── MSG.sunset
│ │ ├── MessageBox.sunset
│ │ ├── MouseEventArgs.sunset
│ │ ├── Net
│ │ │ ├── AddressFamily.sunset
│ │ │ ├── HOSTENT.sunset
│ │ │ ├── IpProtocol.sunset
│ │ │ ├── SOCKADDR_IN
│ │ │ ├── SocketType.sunset
│ │ │ ├── UDPClient.sunset
│ │ │ ├── UDPServer.sunset
│ │ │ ├── WSADATA.sunset
│ │ │ ├── WSAPROTOCOLCHAIN.sunset
│ │ │ └── WSAPROTOCOL_INFOA.sunset
│ │ ├── PaintMsg.sunset
│ │ ├── SYSTEMTIME.sunset
│ │ ├── TimerEventArgs.sunset
│ │ ├── User.sunset
│ │ └── WNDCLASSA.sunset
│ ├── compile.bat
│ ├── compile_bash
│ └── projected syntax.txt
└── Release
│ ├── ProgrammingLanguageTutorialIdea.exe
│ ├── ProgrammingLanguageTutorialIdea.exe.config
│ ├── source.txt
│ └── thing.exe
└── obj
└── Debug
├── .NETFramework,Version=v4.7.1.AssemblyAttributes.cs
├── ProgrammingLanguageTutorialIdea.csproj.FileListAbsolute.txt
├── ProgrammingLanguageTutorialIdea.csprojResolveAssemblyReference.cache
├── ProgrammingLanguageTutorialIdea.exe
├── ProgrammingLanguageTutorialIdea.pdb
├── Sunset.csproj.AssemblyReference.cache
├── Sunset.csproj.CoreCompileInputs.cache
├── Sunset.csproj.FileListAbsolute.txt
├── Sunset.csprojResolveAssemblyReference.cache
├── Sunset.exe
├── Sunset.pdb
├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
└── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.idea/.idea.Sunset/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Rider ignored files
5 | /.idea.Sunset.iml
6 | /projectSettingsUpdater.xml
7 | /modules.xml
8 | /contentModel.xml
9 | # Editor-based HTTP Client requests
10 | /httpRequests/
11 | # Datasource local storage ignored files
12 | /dataSources/
13 | /dataSources.local.xml
14 |
--------------------------------------------------------------------------------
/.idea/.idea.Sunset/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/.idea.Sunset/.idea/indexLayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/.idea.Sunset/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Assembly logic/Array logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | ;Array format and consequently size is
7 | ;Length of array, Size of array member,Array
8 | bytesSize=16 ;This should be:
9 | ;dd, length of array
10 | ;dd, size of each array member
11 | ;... each array member
12 |
13 | ;==== On Array Creation ====
14 |
15 | arrayCreation:
16 | ;Heap Allocation:
17 | push eax ebx ecx
18 | ;Get bytesSize:
19 | mov ebx,2 ;mov in the member size
20 | imul ebx,4;multiply by length
21 | add ebx,8;add in constant 8 bytes (2 uint32)
22 | ;If first heap allocation
23 | call [GetProcessHeap] ;Make this so compiler only runs it once, by storing its value somewhere
24 | mov [processHeapVar],eax
25 | ;Endif
26 | push ebx
27 | mov ebx,00000008h
28 | push ebx
29 | push dword [processHeapVar]
30 | call [HeapAlloc]
31 | ;Storing allocated pointer
32 | mov [heapHandle],eax
33 | pop ecx ebx eax
34 | ;Set initial 8 bytes (UInt32 arrayLength,UInt32 arrayMemberByteSize)
35 | ;This example depicts an array of shorts, or other 2 byte structures, with a length of 4 members (8 bytes)
36 | int3
37 | push 0
38 | push 4
39 | call setArrayValue
40 | int3
41 | push 4
42 | push 2
43 | call setArrayValue
44 |
45 | ;==== End ====
46 |
47 | int3
48 |
49 | ;=== On Array Indexing (SET) ===
50 |
51 | indexArray:
52 | push 1;Array Indexer (Zero-based)
53 | pop eax
54 | imul eax,2;By array member byte size (Shorts=Words=2)
55 | add eax,8;Constant 8
56 | push eax ;Index to set.. 8+(arrayIndexer*arrayMemberByteSize)
57 |
58 | push 255;Value to set
59 | call setArrayValue
60 | jmp setEnd
61 |
62 | ;Accessing the dynamic memory
63 | setArrayValue: ;First time called store this in compiler, after that only call this value
64 | pop edx
65 | pop ebx
66 | pop eax
67 | push edx
68 | add eax,[heapHandle] ;if heapHandle==null in compiler, throw parsingerror
69 | mov [eax],ebx
70 | ret
71 |
72 | ;=== End ===
73 |
74 | setEnd:
75 |
76 | nop
77 | nop
78 | xor ebx,ebx
79 | nop
80 | nop
81 |
82 | ;=== On Array Indexing (GET) ===
83 |
84 | getArrayValue:
85 |
86 | ;Accessing the dynamic memory
87 | push eax ebx
88 | mov eax,[heapHandle]
89 | add eax,10 ;8+(arrayIndexer*arrayMemberByteSize)
90 | mov ebx,[eax]
91 | pop eax ebx
92 | ;Stored in ebx
93 |
94 | ;=== End ===
95 |
96 | ;=== Free arr heap ===
97 |
98 | push dword [heapHandle] ;this is the memory that will be freed
99 | push 0
100 | push dword [processHeapVar] ;this will still be usable I believe (quite certain)
101 | call [HeapFree]
102 |
103 | ;=== End ===
104 |
105 | ret
106 |
107 | heapHandle:
108 | dd 0
109 |
110 | processHeapVar:
111 | dd 0
112 |
113 | section '.idata' import data readable writeable
114 |
115 | dd 0,0,0,RVA kernel_name,RVA kernel_table
116 | dd 0,0,0,0,0
117 |
118 | kernel_table:
119 | HeapAlloc dd RVA _HeapAlloc
120 | GetProcessHeap dd RVA _GetProcessHeap
121 | HeapFree dd RVA _HeapFree
122 | dd 0
123 |
124 | kernel_name db 'kernel32.dll',0
125 |
126 | _HeapAlloc dw 0
127 | db 'HeapAlloc',0
128 | _GetProcessHeap dw 0
129 | db 'GetProcessHeap',0
130 | _HeapFree dw 0
131 | db 'HeapFree',0
132 |
--------------------------------------------------------------------------------
/Assembly logic/Classes and structs.asm:
--------------------------------------------------------------------------------
1 |
2 | ; Possible Issue:
3 | ; - If I programmed an opcode that directly jumps to an address etc..
4 | ; it could potentailly be dangerous if it ends up in a class depending
5 | ; on what it is exactly
6 |
7 | format PE
8 |
9 | start:
10 |
11 | classSize=30 ; Class size in bytes, compiler can get this
12 |
13 | ; Mandatory GetProcessHeap - Functionality in Sunset already implemented
14 | call [GetProcessHeap]
15 | ; - -
16 | ; Heap allocation
17 | push classSize ; Size of class in bytes
18 | push 8 ; Initialize as all blank bytes
19 | push eax ; Push process heap
20 | call [HeapAlloc]
21 | mov dword [classPtr],eax
22 | int3
23 | ; - -
24 | ; copy data at label myClass to heap
25 | mov ecx,classSize ; Size of class in bytes
26 | mov esi,myClass ; Pointer to default class stored in static memory
27 | mov edi,eax ; Pointer to new heap
28 | rep movsb ; Repeat copy the bytes in
29 | ; - -
30 | ; new(ClassName)
31 | call eax ; Jump to start of heap to run through class, (when the "new" keyword is called, i.e new(MyClass))
32 | ; - -
33 | ; calling a function in a class
34 | ; classInstance.functionCall
35 |
36 | mov eax,dword [classPtr]
37 | add eax,10 ; offset to functionEx0
38 | call eax ; Would call label functionEx0
39 |
40 | ; - -
41 | ; Accessing variable from class
42 | mov eax,dword [classPtr]
43 | add eax,classSize-8 ; offset to variableEx
44 | add dword [eax],5 ; add 5 to the variable
45 | ; - -
46 |
47 | ; (Extra) See changes of class variable in OllyDBG
48 | mov eax,dword [classPtr]
49 | jmp eax
50 |
51 | retn ; Return with return exit code from label functionEx0
52 |
53 | classPtr:
54 | dd 0
55 |
56 | ; Default class will be stored static in memory in appendAfter
57 | ; (Compiler can easily detect byte size of blocks parsed in)
58 | myClass:
59 |
60 | jmp functionExEnd ; 2 bytes
61 | functionEx:
62 | mov eax,13 ;5 bytes
63 | retn ; 1 byte
64 | functionExEnd:
65 |
66 | jmp functionEx0End ; 2 bytes
67 | functionEx0:
68 | mov eax,145 ;5 bytes
69 | retn ; 1 byte
70 | functionEx0End:
71 |
72 | mov eax,123 ;5 bytes
73 | retn ; 1 byte
74 |
75 | variableEx:
76 | dd 123 ;4 bytes
77 |
78 | variableEx0:
79 | dd 1234 ;4 bytes
80 |
81 | ;Total class block size: 26 bytes
82 |
83 | section '.idata' import data readable writeable
84 |
85 | dd 0,0,0,RVA kernel_name,RVA kernel_table
86 | dd 0,0,0,0,0
87 |
88 | kernel_table:
89 | HeapAlloc dd RVA _HeapAlloc
90 | GetProcessHeap dd RVA _GetProcessHeap
91 | dd 0
92 |
93 | kernel_name db 'KERNEL32.DLL',0
94 |
95 | _HeapAlloc dw 0
96 | db 'HeapAlloc',0
97 | _GetProcessHeap dw 0
98 | db 'GetProcessHeap',0
--------------------------------------------------------------------------------
/Assembly logic/Foreach loops logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | foreachBlockPrecursor:
7 | xor ecx,ecx
8 | foreachBlockContinueAddr:
9 | mov ebx,[dwordArray]
10 | cmp ecx,[ebx]
11 | jz foreachBlockEnd
12 | mov eax,[ebx+4]
13 | mul ecx
14 | add eax,ebx
15 | push dword [eax+8] ; Compiler stores local var on pseudoStack
16 | ; ^ Should check for var type byte size first
17 | inc ecx
18 | foreachBlockStart:
19 | push ecx ; Compiler stores preserved ECX on pseudoStack
20 | enter 0,0
21 |
22 | ; .... Block instructions
23 | ; Acessing local var normally:
24 | mov eax,[ebp+8]
25 | int3
26 |
27 | leave
28 | pop ecx
29 | add esp,4 ; Compiler removes local var from pseudoStack
30 | jmp foreachBlockContinueAddr
31 | foreachBlockEnd:
32 |
33 | ; ---------------
34 | xor eax,eax
35 | retn
36 | ; ---------------
37 |
38 |
39 | dwordArray:
40 | dd dwordArrayMem
41 | dwordArrayMem:
42 |
43 | ; ----------------
44 | ; Array length
45 | dd 7
46 | ; Array member byte size
47 | dd 4
48 | ; ----------------
49 | ; Array members
50 | ; ----------------
51 | dd 3
52 | rd 2
53 | dd 6
54 | dd 4
55 | rd 2
56 |
--------------------------------------------------------------------------------
/Assembly logic/Functions, local vars, parameters logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | ;== No params ==
7 | noParams:
8 | jmp someFunctionBlockEnd ;Initially skip the function
9 | someFunction:
10 |
11 | ;...Function code here
12 | int3
13 | nop
14 |
15 | ;Returning value:
16 | mov eax,123
17 | ret ;Value in EAX is returned value
18 |
19 | someFunctionBlockEnd:
20 |
21 | call someFunction ; .. calling function
22 | ;... EAX contains return value here
23 |
24 | ;== Params & Local Vars ==
25 |
26 | localVarsCount=2
27 |
28 | params:
29 |
30 | jmp otherFunctionBlockEnd
31 | otherFunction: ; 2 Parameters
32 |
33 | enter localVarsCount*4,0
34 |
35 | ;...Function code here
36 |
37 | ;Creating local var:
38 | mov dword [ebp-8],1
39 |
40 | ;To access local vars:
41 | push dword [ebp-4] ; EBP-((Local Var Index * 4)+4)
42 |
43 | ;To access parameters
44 | push dword [ebp+8] ; EBP+((Param Index * 4)+8)
45 |
46 | ;Popping value into a local var
47 | pop dword [ebp-8]
48 |
49 | leave
50 | ret
51 |
52 | otherFunctionBlockEnd:
53 |
54 | ;Calling function..
55 | push 2 ; Push parameter
56 | push 3 ; via pushValue
57 | call otherFunction ; Call function
58 |
59 | xor eax,eax ; exit code 0
60 | ret ; exit process
--------------------------------------------------------------------------------
/Assembly logic/Multi foreach logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 | setup:
6 |
7 | ; Getting the array with the lowest count (length),
8 | ; result is placed in ECX then moved to the stack:
9 |
10 | jmp donePutLocalVar
11 | putLocalVar: ; Make a local var from array index
12 | ; (For later)
13 | mov eax,[ebx+4] ; Get array member byte size
14 | mul ecx
15 | add eax,ebx
16 | mov eax,[eax+8]
17 | retn ; Return doesn't clear parameters because they are stored in registers
18 | ; (EBX=array addr, ECX=array index)
19 |
20 | donePutLocalVar:
21 |
22 | ; First array
23 | mov ecx,[arrayOne]
24 | ; -----------
25 |
26 | ; Every following array
27 | cmp [arrayTwo],ecx
28 | jge nextArray
29 | mov ecx,[arrayTwo]
30 | nextArray:
31 | ; -----------------
32 |
33 | doneQuery:
34 | push ecx ; Store ecx on stack
35 | ; Compiler: store on pseudoStack
36 | xor ecx,ecx ; Zero ecx
37 |
38 | continueAddr: ; 'continue' keyword will be directed here
39 | cmp ecx,[esp] ; Compare ECX to loop count stored on stack
40 | jz b_end ; Jump to block end if done looping
41 |
42 | arrayOne_putLocalVar: ; Repeat these instructions per array
43 | mov ebx,arrayOne
44 | call putLocalVar
45 | push eax ; Store local var on pseudoStack
46 | ; ---------------------------------------------
47 |
48 | arrayTwo_putLocalVar: ; ...
49 | mov ebx,arrayTwo
50 | call putLocalVar
51 | push eax ; Store local var on pseudoStack
52 | ; ---------------------------------------------
53 |
54 | inc ecx ; Increase iteration #
55 |
56 | blockStart:
57 | push ecx ; Store ecx (iteration #)
58 | enter 0,0 ; Enter block...
59 |
60 | ; ... Block instructions
61 |
62 | leave ; Leave block...
63 | pop ecx ; Restore ecx (iteration #)
64 | add esp,8 ; Restore stack from all local variables
65 | ; Compiler removes all local variables from pseudoStack
66 | ; Number to add to ESP is # of arrays * 4 (2 * 4 = 8)
67 | jmp continueAddr ; Loop
68 |
69 | b_end: add esp,4 ; Clear preserved ecx
70 | p_end: xor eax,eax ; Exit code 0
71 | retn ; Exit process
72 |
73 |
74 |
75 | arrayOne:
76 |
77 | ; Length
78 | dd 6
79 | ; Mem size
80 | dd 4
81 |
82 | dd 3
83 | rd 4
84 | dd 2
85 |
86 | arrayTwo:
87 |
88 | ; Length
89 | dd 7
90 | ; Mem size
91 | dd 4
92 |
93 | dd 2
94 | rd 6
95 |
--------------------------------------------------------------------------------
/Assembly logic/Stack instruction execution.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | ; This isn't important but I found it
7 | ; while debugging, and messed around
8 | ; with it. It's pretty cool
9 | ; (This will return exit code 16, or any 0-255 if you set it to do so)
10 |
11 | mov ebp,esp
12 | push 9090C3ECh
13 | push 08958166Ah
14 | jmp esp
15 |
16 | ; Revision 8/5/2021 2:56AM:
17 | ; This proved to be useful as instructions
18 | ; were ran off the heap in classes. That was
19 | ; earlier than the revision date
--------------------------------------------------------------------------------
/Assembly logic/String logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | ;... Setting ptr
7 | push myStr
8 | pop dword [myStrPtr]
9 |
10 | ; Passing the string in as arguments for a dllreference
11 | ; (which will be implemented afterwards)
12 | push 0
13 | push dword [myStrPtr]
14 | push dword [myStrPtr]
15 | push 0
16 | call [MessageBoxA]
17 |
18 | ; int3 ; pause
19 | xor eax,eax ; exit code 0
20 | ret ; exit process
21 |
22 |
23 | ; When a String is declared, it will be stored as so:
24 | ; (Always static, no heap, at least I see that as the best way for now)
25 | ; When the variable is ever passed,
26 | ; it will be passed as a pointer to this
27 | myStr:
28 | db 'Hello world',0 ; < 0 is the end null byte, expected on each string, on any programming language, to my knowledge (perhaps there are exceptions)
29 |
30 | myStrPtr:
31 | dd 0
32 |
33 | ; ------------------------------------------------
34 | section '.idata' import data readable writeable
35 |
36 | dd 0,0,0,RVA user_name, RVA user_table
37 | dd 0,0,0,0,0
38 |
39 | user_table:
40 | MessageBoxA dd RVA _MessageBoxA
41 | dd 0
42 |
43 | user_name db 'USER32.DLL',0
44 |
45 | _MessageBoxA dw 0
46 | db 'MessageBoxA',0
--------------------------------------------------------------------------------
/Assembly logic/While loops logic.asm:
--------------------------------------------------------------------------------
1 |
2 | format PE
3 |
4 | start:
5 |
6 | whileBlockStart:
7 |
8 | ; -- If check --
9 |
10 | ; this varies based on parameters
11 | ; as well as the boolean operator
12 | ; if 3 parameters are used. The
13 | ; logic is the same as KWIf.cs
14 |
15 | push dword [someInt] ; pushValue
16 | pop eax
17 | push dword [otherInt] ; pushValue
18 | pop edx
19 | cmp eax,edx
20 |
21 | ; -------------------------------------------------------
22 | ; - Boolean condition (if greater than in this example) -
23 | jng whileBlockEnd
24 | ; -------------------------------------------------------
25 |
26 | ; -- -- -- -- --
27 |
28 | ; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
29 | ; Code inside while block goes in this section
30 | ; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
31 |
32 | inc dword [otherInt] ;++otherInt
33 |
34 | ; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
35 |
36 | jmp whileBlockStart
37 |
38 | whileBlockEnd:
39 |
40 | xor eax,eax ; exit code 0
41 | ret ; exit process
42 |
43 | someInt:
44 | dd 6
45 |
46 | otherInt:
47 | dd 3
48 |
--------------------------------------------------------------------------------
/Assembly logic/datasect_test.ASM:
--------------------------------------------------------------------------------
1 | format PE
2 |
3 | mov eax,[someStaticVar]
4 | mov edx,eax
5 | call staticFunc
6 | add eax,edx
7 | retn
8 |
9 |
10 | section '.data' data readable writeable
11 |
12 | someStaticVar: dd 1234
13 |
14 | otherStaticVar: dd 1234
15 |
16 | staticFunc:
17 | mov eax,123
18 | retn
19 |
20 |
21 | ; Test 512 + bytes in data func
22 | ; Also test without .idata section
23 |
24 | section '.idata' import data readable writeable
25 |
26 | dd 0,0,0,RVA user_name, RVA user_table
27 | dd 0,0,0,RVA kernel_name, RVA kernel_table
28 | dd 0,0,0,0,0
29 |
30 | user_table:
31 |
32 | MessageBoxA dd RVA _MessageBoxA
33 | dd 0
34 |
35 | kernel_table:
36 |
37 | HeapAlloc dd RVA _HeapAlloc
38 | GetProcessHeap dd RVA _GetProcessHeap
39 | dd 0
40 |
41 | user_name db 'USER32.DLL',0
42 | kernel_name db 'KERNEL32.DLL',0
43 |
44 | _MessageBoxA dw 0
45 | db 'MessageBoxA',0
46 | _HeapAlloc dw 0
47 | db 'HeapAlloc',0
48 | _GetProcessHeap dw 0
49 | db 'GetProcessHeap',0
--------------------------------------------------------------------------------
/Assembly logic/datasect_test.EXE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Assembly logic/datasect_test.EXE
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Jake Frey
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sunset
2 |
3 | **Sunset** is a custom-built, Turing-complete programming language developed in C#. It features a fully self-written tokenizer, parser, and compiler capable of generating standalone executable files. Designed as both an educational tool and a serious compiler project, Sunset demonstrates deep knowledge of language design, compiler architecture, and low-level code generation.
4 |
5 | ---
6 |
7 | ## Features
8 |
9 | - **Self-Written Compiler and Parser**: Built entirely in C#, Sunset tokenizes and parses source code without external libraries. It compiles to native assembly and produces runnable `.exe` files.
10 | - **Turing-Complete Language**: Sunset can be rewritten in Sunset and the libraries are written in Sunset
11 | - **Standalone Executable Generation**: Sunset can compile your `.sunset` files into native Windows executables — no runtime needed.
12 | - **Cross-Platform Design**: Designed with cross-platform compatibility in mind; current builds and testing focused on Windows.
13 | - **Self-Implemented Standard Library**: Sunset's standard functions are written in Sunset itself, proving the language is expressive enough to support real-world usage.
14 | - **Assembly Output Logic**: The compiler emits clean, structured assembly to support logic like arrays, string handling, loops, functions, and classes.
15 | - **Syntax Highlighting Support**: Comes with an EmEditor `.esy` file for syntax highlighting.
16 |
17 | ---
18 |
19 | ## Example Code
20 |
21 | ```sunset
22 | public static func(int num) absolute int {
23 |
24 | if (num,<,0) {
25 | retn(num*(-1))
26 | }
27 | retn(num)
28 |
29 | }
30 | ```
31 |
32 | ---
33 |
34 | ## Compiler Architecture
35 |
36 | Sunset is composed of several compiler stages:
37 |
38 | - **Tokenizer**: Parses source text character by character into tokens (identifiers, numbers, symbols, etc.)
39 | - **Parser**: Converts tokens into abstract syntax trees, handling precedence and nesting
40 | - **Code Generator**: Emits custom assembly logic for a stack-based execution model
41 | - **Executable Builder**: Compiles final assembly into `.exe` files
42 |
43 | Assembly logic covers:
44 |
45 | - Array handling
46 | - Class and struct logic
47 | - Control flow (if/while/foreach)
48 | - String manipulation
49 | - Function parameters and local variables
50 | - Stack instruction execution
51 |
52 | All available under `/Assembly logic/`.
53 |
54 | ---
55 |
56 | ## Getting Started
57 |
58 | 1. **Clone the Repository**:
59 |
60 | ```bash
61 | git clone https://github.com/jakefrey0/Sunset.git
62 | ```
63 |
64 | 2. **Open the Solution**:
65 |
66 | Open `Sunset.sln` in Visual Studio.
67 |
68 | 3. **Build the Project**:
69 |
70 | Build the solution to generate the Sunset compiler.
71 |
72 | 4. **Write & Compile Sunset Code**:
73 |
74 | Create `.sunset` source files and compile them:
75 | ```bash
76 | sunset your_file.sunset
77 | ```
78 |
79 | ---
80 |
81 | ## Syntax Highlighting
82 |
83 | Use EmEditor? Import the syntax file for Sunset code coloring:
84 |
85 | ```
86 | Sunset/bin/Debug/Sunset_Syntax.esy
87 | ```
88 |
89 | ---
90 |
91 | ## Example Project
92 |
93 | Explore an early Sunset program:
94 | - [Simple RPG in Sunset (2022/08/10)](https://github.com/cashsignsesh/Simple-RPG)
95 |
96 | Preview:
97 | 
98 |
99 | ---
100 |
101 | ## Roadmap
102 |
103 | - [x] Custom compiler in C#
104 | - [x] Executable output (.exe)
105 | - [x] Core features: loops, arrays, structs, functions
106 | - [ ] Type system improvements
107 | - [ ] Runtime error reporting
108 | - [ ] Basic IDE or CLI debugger
109 |
110 | ---
111 |
112 | ## License
113 |
114 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
115 |
116 | ---
117 |
118 | ## Author
119 |
120 | Created and maintained by [Jake Frey](https://github.com/jakefrey0)
121 |
--------------------------------------------------------------------------------
/Sunset.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | # SharpDevelop 4.4
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sunset", "Sunset\Sunset.csproj", "{19D2E25E-77E6-443C-B6EB-2E58499E4104}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Release|Any CPU.Build.0 = Release|Any CPU
16 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | EndGlobalSection
18 | EndGlobal
19 |
--------------------------------------------------------------------------------
/Sunset/ArrayStyle.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/3/2021
5 | * Time: 12:15 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum ArrayStyle {
14 |
15 | DYNAMIC_MEMORY_HEAP,STATIC_MEMORY_BLOCK,STACK_ALLOCATION
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/Block.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/7/2021
5 | * Time: 4:13 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Linq;
12 |
13 | namespace Sunset {
14 |
15 | public class Block {
16 |
17 | public readonly Action onBlockEnd;
18 | public UInt32 startMemAddr;
19 | public UInt32 endMemAddr {
20 |
21 | private set;
22 | get;
23 |
24 | }
25 | public readonly Byte[] opcodesToAddOnBlockEnd;
26 |
27 | public Dictionary>> localVariables;
28 | public Dictionary arrayStyles;
29 |
30 | public readonly Boolean shouldXOREAX,addEnterAutomatically;
31 |
32 | public UInt16 nestedLevel=0;
33 |
34 | public ListblockMemPositions;
35 | public List>blockRVAPositions;
36 |
37 | public Boolean isLoopOrSwitchBlock=false,switchBlock=false,caseOrDefaultBlock=false,hasParentheses=true;
38 | public UInt32 continueAddress=0;
39 |
40 | ///
41 | /// i.e If & Else
42 | ///
43 | public Block pairedBlock {
44 |
45 | get;
46 | protected set;
47 |
48 | }
49 |
50 | public Byte[] breakInstructions,continueInstructions;
51 | ///
52 | /// For after the block is fully closed (i.e all leave statements)
53 | /// These will be appended last on the block closing process
54 | /// (Optional as are all non-constructor items)
55 | ///
56 | public Byte[] afterBlockClosedOpcodes;
57 | public Action afterBlockClosedFunc;
58 |
59 | public ListrestoreArraySetValueFuncs;
60 | private Listchildren;
61 |
62 | public Block (Action onBlockEnd,UInt32 startMemAddr,Byte[] opcodesToAddOnBlockEnd,Boolean xorEax=false,Boolean addEnterAutomatically=true) {
63 |
64 | this.startMemAddr=startMemAddr;
65 | this.onBlockEnd=onBlockEnd;
66 | this.opcodesToAddOnBlockEnd=opcodesToAddOnBlockEnd;
67 | this.localVariables=new Dictionary>>();
68 | this.shouldXOREAX=xorEax;
69 | this.addEnterAutomatically=addEnterAutomatically;
70 | this.blockMemPositions=new List();
71 | this.blockRVAPositions=new List>();
72 | this.restoreArraySetValueFuncs=new List();
73 | this.children=new List();
74 | this.arrayStyles=new Dictionary();
75 |
76 | }
77 |
78 | public static void pairBlocks (Block b,Block b0) {
79 |
80 | b.pairedBlock=b0;
81 | b0.pairedBlock=b;
82 |
83 | }
84 |
85 | public void addChild (Block child) { this.children.Add(child); }
86 |
87 | public Boolean hasChild (Block child) {
88 |
89 | if (children.Contains(child))
90 | return true;
91 | return children.Count>0&&children.Any(x=>x.hasChild(child));
92 |
93 | }
94 |
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/Sunset/Class.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/11/2021
5 | * Time: 2:50 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Runtime.InteropServices;
12 | using Sunset.VarTypes;
13 |
14 | namespace Sunset {
15 |
16 | public class Class {
17 |
18 | public readonly String className,path,classID;
19 | public readonly UInt32 byteSize,opcodePortionByteSize,skeletonIndex,classAppendAfterCount,bytesToReserve,inhTblAppendAfterIndex;
20 | public readonly ClassType classType;
21 | public readonly Parser parserUsed;
22 | public Dictionary>variables;
23 | public Dictionary>classes;//Name,(Offset To Mem Address of Heap Handle,Class type name,Class type),Instance ID
24 | public Dictionaryfunctions;//Function Name,(Memory Address,(Return Type, Return Var Type),No. of expected parameters,Function Type,Calling Convention,Modifiers)
25 | public Dictionary> arrays=new Dictionary>();//Name,(Ptr To Mem Address of Heap Handle(Dynamic) or Mem Block(Static),Array Var Type,ArrayStyle(Dynamic or Static)),Instance ID
26 | public Tuple>> constructor;//Memory Address,Func Param Types
27 | public Dictionary,Modifier>>constants=new Dictionary,Modifier>>();//var name,(constant value,(Generic Var Type Tuple))
28 | private ListdefineTimeOrder;
29 | public ListinheritedClasses;
30 |
31 | public Class (String className,String path,UInt32 byteSize,ClassType classType,Parser parserUsed,UInt32 opcodePortionByteSize,UInt32 skeletonIndex,UInt32 classAppendAfterCount,String classID) {
32 |
33 | this.bytesToReserve=parserUsed.byteCountBeforeDataSect;
34 | this.className=className;
35 | this.byteSize=byteSize;
36 | this.classType=classType;
37 | this.variables=new Dictionary>();
38 | this.classes=new Dictionary>();
39 | this.functions=new Dictionary();
40 | this.defineTimeOrder=new List(parserUsed.defineTimeOrder);
41 | this.opcodePortionByteSize=opcodePortionByteSize;
42 | this.skeletonIndex=skeletonIndex;
43 | this.classAppendAfterCount=classAppendAfterCount;
44 | this.parserUsed=parserUsed;
45 | foreach (KeyValuePair>kvp in parserUsed.getVariables())
46 | this.variables.Add(kvp.Key,new Tuple(kvp.Value.Item1-parserUsed.memAddress,kvp.Value.Item2,kvp.Value.Item3,kvp.Value.Item4));
47 | foreach (KeyValuePair>kvp in parserUsed.getClasses()) {
48 | if (kvp.Value.Item1==0) this.classes.Add(kvp.Key,new Tuple(0,kvp.Value.Item2,kvp.Value.Item3,kvp.Value.Item4,kvp.Value.Item5));
49 | else this.classes.Add(kvp.Key,new Tuple(kvp.Value.Item1-parserUsed.memAddress,kvp.Value.Item2,kvp.Value.Item3,kvp.Value.Item4,kvp.Value.Item5));
50 | }
51 | foreach (KeyValuePair kp in parserUsed.getFunctions()) {
52 | this.functions.Add(kp.Key,kp.Value);
53 | }
54 | foreach (KeyValuePair>kvp in parserUsed.getArrays())
55 | this.arrays.Add(kvp.Key,new Tuple(kvp.Value.Item1-parserUsed.memAddress,kvp.Value.Item2,kvp.Value.Item3,kvp.Value.Item4,kvp.Value.Item5));
56 | this.constructor=parserUsed.constructor;
57 | this.constants=parserUsed.getConstants();
58 | this.path=path;
59 | this.classID=classID;
60 | this.inheritedClasses=new List(parserUsed.inheritedClasses);
61 | this.inhTblAppendAfterIndex=parserUsed.inhTblAppendAfterIndex;
62 | }
63 |
64 | public Tuple getVarType (String name) {
65 |
66 | if (variables.ContainsKey(name))
67 | return new Tuple(this.variables[name].Item2,VarType.NATIVE_VARIABLE);
68 | else if (classes.ContainsKey(name))
69 | return new Tuple(this.classes[name].Item2,VarType.CLASS);
70 | else if (functions.ContainsKey(name))
71 | return this.functions[name].returnType;
72 | else if (arrays.ContainsKey(name))
73 | return new Tuple(this.arrays[name].Item2,VarType.NATIVE_ARRAY_INDEXER);
74 | else throw new ParsingError("Variable \""+name+"\" does not exist in \""+className+"\" (?!)",null);
75 |
76 | }
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/Sunset/ClassType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/11/2021
5 | * Time: 5:19 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum ClassType {
14 |
15 | NORMAL,STRUCT,ENUM
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/CompileType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: GDSPIOSJDGOSDHGJSDhg
4 | * Date: 9/14/2022
5 | * Time: 5:12 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum CompileType {
14 | WINDOWS,NON_FORMATTED_BINARY
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/Sunset/Executor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/10/2021
5 | * Time: 12:50 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using Sunset.Keywords;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset {
14 |
15 | public struct Executor {
16 |
17 | public Keyword kw;
18 | public String func;
19 | ///
20 | /// Class Origin,Func,Is origin local
21 | ///
22 | public Tuple,String,Boolean>classFunc;
23 | public TupleexternalStaticFunc;
24 | public TupleinternalStaticFunc;
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/Sunset/FunctionType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/19/2021
5 | * Time: 6:42 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum FunctionType {
14 |
15 | DLL_REFERENCED,SUNSET
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWAcknowledge.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWAcknowledge : Keyword {
5 |
6 | public const String constName="acknowledge";
7 |
8 | public KWAcknowledge () : base(constName,KeywordType.TYPE_DEFINITION) { }
9 |
10 | public override KeywordResult execute (Parser sender,String[] @params) {
11 |
12 | Keyword.throwIfShouldBeHeader(sender,constName);
13 |
14 | return new KeywordResult() { newStatus=ParsingStatus.SEARCHING_TYPE_DEFINITION_NAME,newOpcodes=new Byte[0] };
15 |
16 | }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWAs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWAs : Keyword {
5 |
6 | public const String constName="as";
7 |
8 | public KWAs () : base (constName,KeywordType.TYPE_DEFINITION_ASSIGNEMENT) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | if (String.IsNullOrEmpty(sender.rTypeDefinition))
13 | throw new ParsingError("Got keyword \""+constName+"\" outside of a type acknowledgement context",sender);
14 |
15 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.TYPE};
16 | return base.execute(sender,@params);
17 |
18 | }
19 |
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/Sunset/Keywords/KWBecomes.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 11:32 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWBecomes : Keyword {
14 |
15 | public const String constName="becomes";
16 |
17 | public KWBecomes () : base (constName,KeywordType.ASSIGNMENT) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | if (String.IsNullOrEmpty(sender.lastReferencedVariable))
22 | throw new ParsingError("Invalid use of \""+constName+"\", no referenced variable found",sender);
23 |
24 | sender.referencedVariable=sender.lastReferencedVariable;
25 | sender.referencedVarType=sender.lastReferencedVarType;
26 | sender.referencedVariableIsLocal=sender.lastReferencedVariableIsLocal;
27 | sender.referencedVariableIsFromClass=sender.lastReferencedVariableIsFromClass;
28 | sender.referencedVariableIsStatic=sender.lastReferencedVariableIsStatic;
29 | sender.lastReferencedVariableIsStatic=false;
30 | Console.WriteLine("Becomes: referencedVariableIsLocal: "+sender.referencedVariableIsLocal.ToString());
31 |
32 | Byte[] newOpcodes=new Byte[0];
33 |
34 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VALUE,newOpcodes=newOpcodes};
35 |
36 | }
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWBoolean.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/8/2021
5 | * Time: 12:47 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWBoolean : Keyword {
14 |
15 | public const String constName="bool",//maybe call this "twofold" cause it's funny
16 | constTrue="true",
17 | constFalse="false";
18 |
19 | public KWBoolean () : base (constName,KeywordType.TYPE) { }
20 |
21 | public override KeywordResult execute (Parser sender,String[] @params) {
22 |
23 | //booleans will be false by default since 0==false
24 |
25 | sender.varType=this.name;
26 | sender.lastReferencedVarType=VarType.NATIVE_VARIABLE;
27 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
28 |
29 | }
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWBreak.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/20/2021
5 | * Time: 5:21 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset.Keywords {
14 |
15 | public class KWBreak : Keyword {
16 |
17 | public const String constName="break";
18 |
19 | public KWBreak () : base (constName,KeywordType.NATIVE_CALL) { }
20 |
21 | public override KeywordResult execute (Parser sender,String[]@params) {
22 |
23 | if (sender.blocks.Count==0)
24 | throw new ParsingError("Can't break outside of a block",sender);
25 |
26 | Action ac=null;
27 | Block block=(sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Count()==0)?sender.blocks.Keys.Last():sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Last();
28 |
29 | ListnewOpcodes=new List(new Byte[]{0xC9,0xE9,0,0,0,0});
30 | if (sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Count()==0) {
31 | block.blockRVAPositions.Add(new Tuple((UInt32)(sender.GetStaticInclusiveOpcodesCount().index+2+(block.breakInstructions==null?0:block.breakInstructions.Length)),(UInt32)(sender.GetStaticInclusiveAddress()+6+(block.breakInstructions==null?0:block.breakInstructions.Length))));
32 | if (block.breakInstructions!=null)
33 | newOpcodes.InsertRange(1,block.breakInstructions);
34 | }
35 | else {
36 |
37 | UInt32 bonusLeaves=(UInt32)(sender.blocks.Count-sender.blocks.Keys.Cast().ToList().IndexOf(sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Last()))-1;
38 | ac=delegate {
39 | Block block0=sender.blocks.Keys.Last();
40 | if (block0.caseOrDefaultBlock) {
41 |
42 | --bonusLeaves;
43 | sender.closeBlock(block0);
44 |
45 | }
46 | };
47 | Byte[]leaves=new Byte[bonusLeaves];
48 | UInt32 i=0;
49 | while (i!=leaves.Length) {
50 |
51 | leaves[i]=0xC9;
52 | ++i;
53 |
54 | }
55 | newOpcodes.InsertRange(0,leaves);
56 | sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Last().blockRVAPositions.Add(new Tuple((UInt32)(sender.GetStaticInclusiveOpcodesCount().index+2+bonusLeaves+(block.breakInstructions==null?0:block.breakInstructions.Length)),(UInt32)(sender.GetStaticInclusiveAddress()+6+bonusLeaves+(block.breakInstructions==null?0:block.breakInstructions.Length))));
57 |
58 | if (block.breakInstructions!=null)
59 | newOpcodes.InsertRange((Int32)bonusLeaves+1,block.breakInstructions);
60 |
61 | }
62 |
63 | return new KeywordResult(){newOpcodes=newOpcodes.ToArray(),newStatus=ParsingStatus.SEARCHING_NAME,action=ac};
64 | }
65 |
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWByte.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:59 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWByte : Keyword {
14 |
15 | public const String constName="byte";
16 |
17 | public KWByte () : base (constName,KeywordType.TYPE) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | sender.varType=this.name;
22 | sender.lastReferencedVarType=VarType.NATIVE_VARIABLE;
23 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
24 |
25 | }
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWByteSizeOf.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/11/2021
5 | * Time: 2:05 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWByteSizeOf : Keyword {
15 |
16 | public const String constName="Bsizeof";
17 |
18 | public KWByteSizeOf () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | if (@params.Length!=1)
23 | throw new ParsingError("Expected 1 parameter for \""+constName+"\", got "+@params.Length.ToString()+" parameters",sender);
24 |
25 | if (!sender.importedClasses.Select(x=>x.className).Contains(@params[0]))
26 | throw new ParsingError("Class does not exist/is not imported: \""+@params[0]+'"',sender);
27 |
28 | sender.addBytes(new Byte[]{0xB8}.Concat(BitConverter.GetBytes(sender.importedClasses.Where(x=>x.className.Equals(@params[0])).First().byteSize))); //MOV EAX,DWORD
29 | outputType=new Tuple(KWInteger.constName,VarType.NATIVE_VARIABLE);
30 |
31 | return base.execute(sender, @params);
32 |
33 | }
34 |
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWCallptr.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/5/2021
5 | * Time: 5:51 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | ///
15 | /// This is an unsafe keyword because it requires the parameters to be their expected values, though it places no restrictions (as the compiler doesn't know any)
16 | ///
17 | public class KWCallptr : Keyword {
18 |
19 | public const String constName="callptr";
20 |
21 | public KWCallptr () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE,true) { }
22 |
23 | public override KeywordResult execute(Parser sender,String[] @params) {
24 |
25 | if (@params.Length==0)
26 | throw new ParsingError("Expected at least 1 parameter for \""+constName+"\" (func address as \""+KWInteger.constName+"\", + optional function parameters)",sender);
27 |
28 | outputType=Parser.FUNC_PTR;
29 | TupleinputType=sender.pushValue(@params[0]);
30 | if (!inputType.Equals(outputType))
31 | throw new ParsingError("Expected a FUNCTION POINTER (\""+Parser.FUNC_PTR_STR+"\") as the first parameter of \""+constName+"\", as the func address! (Got: "+inputType.Item1+')',sender);
32 |
33 | Byte i=0;
34 |
35 | if (@params.Length!=1) {
36 | foreach (String s in @params.Skip(1)) {
37 | sender.pushValue(s);
38 | i+=4;
39 | }
40 | }
41 |
42 | sender.addBytes(new Byte[]{0xFF,0x54,0x24,i}); //CALL [ESP+-OFFSET]
43 | sender.addBytes(new Byte[]{0x83,0xC4,4}); //ADD ESP,4
44 |
45 | return base.execute(sender, @params);
46 |
47 | }
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWCase.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/6/2021
5 | * Time: 6:18 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWCase : Keyword {
15 |
16 | public const String constName="case";
17 |
18 | public KWCase () : base (constName,KeywordType.NATIVE_CALL,true) { }
19 |
20 | public override KeywordResult execute(Parser sender,String[] @params) {
21 | if (@params.Length==0) throw new ParsingError("Expected at least 1 parameter for \""+constName+'"',sender);
22 | if (sender.blocks.Keys.Where(x=>x.switchBlock).Count()==0) throw new ParsingError("Can't \""+constName+"\" outside of a \""+KWSwitch.constName+"\" block.",sender);
23 | KWCase.checkForCaseFallThrough(sender);
24 | Block caseBlock=null;
25 | caseBlock=new Block(null,sender.GetStaticInclusiveAddress(),new Byte[0],false){caseOrDefaultBlock=true,hasParentheses=false};
26 | if (@params.Length==1) {
27 | sender.pushValue(@params[0]);
28 | sender.addByte(0x58); //POP EAX
29 | sender.addBytes(new Byte[]{0x3B,0x45,sender.pseudoStack.getLatestSwitchVarOffset()}); //CMP EAX,[EBP+-OFFSET]
30 | caseBlock.blockMemPositions.Add(sender.GetStaticInclusiveOpcodesCount(2));
31 | sender.addBytes(new Byte[]{0x0F,0x85,0,0,0,0});//JNZ
32 | caseBlock.startMemAddr=sender.GetStaticInclusiveAddress();
33 | sender.addBlock(caseBlock,0);
34 | }
35 | else {
36 |
37 | Int32 pl=@params.Length;
38 | Tuple[]toBlockStart=new Tuple[pl];
39 | UInt16 i=0;
40 | while (i!=pl) {
41 |
42 | sender.pushValue(@params[i]);
43 | sender.addByte(0x58); //POP EAX
44 | sender.addBytes(new Byte[]{0x3B,0x45,sender.pseudoStack.getLatestSwitchVarOffset()}); //CMP EAX,[EBP+-OFFSET]
45 | toBlockStart[i]=new Tuple(sender.GetStaticInclusiveOpcodesCount().index+2,sender.GetStaticInclusiveAddress());
46 | sender.addBytes(new Byte[]{0x0F,0x84,0,0,0,0});//JZ
47 | ++i;
48 |
49 | }
50 | caseBlock.blockMemPositions.Add(sender.GetStaticInclusiveOpcodesCount(1));
51 | sender.addBytes(new Byte[]{0xE9,0,0,0,0});//JMP
52 | Byte[]memAddr;
53 |
54 | foreach (Tupletpl in toBlockStart) {
55 |
56 | memAddr=BitConverter.GetBytes((Int32)sender.GetStaticInclusiveAddress()-(Int32)tpl.Item2-6);
57 | i=0;
58 |
59 | while (i!=4) {
60 |
61 | if (sender.InStaticEnvironment()) Parser.dataSectBytes[(Int32)(tpl.Item1+i)]=memAddr[i];
62 | else sender.setByte(tpl.Item1+i,memAddr[i]);
63 | ++i;
64 |
65 | }
66 |
67 |
68 | }
69 | caseBlock.startMemAddr=sender.GetStaticInclusiveAddress();
70 | sender.addBlock(caseBlock,0);
71 |
72 |
73 | }
74 |
75 | return new KeywordResult(){newOpcodes=new Byte[0],newStatus=ParsingStatus.SEARCHING_COLON};
76 |
77 |
78 | }
79 |
80 | public static void checkForCaseFallThrough (Parser sender) {
81 |
82 | Block lastBlock=sender.blocks.Keys.Last();
83 | if (lastBlock.caseOrDefaultBlock) {
84 | lastBlock.afterBlockClosedOpcodes=null;
85 | sender.closeBlock(lastBlock);
86 | }
87 |
88 | }
89 |
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWCast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWCast : Keyword {
5 |
6 | public const String constName="cast";
7 |
8 | public KWCast () : base(constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE,true) {}
9 |
10 | public override KeywordResult execute(Parser sender,String[] @params) {
11 |
12 | if (@params.Length!=2)
13 | throw new ParsingError("Expected 2 parameters for \""+constName+"\", instance name and variable type respectively",sender);
14 |
15 | TuplefirstType=sender.pushValue(@params[0]),secondType=sender.getVarType(@params[1]);
16 |
17 | UInt32 resultB_Size=sender.keywordMgr.getVarTypeByteSize(secondType.Item1);
18 |
19 | if (sender.acknowledgements.ContainsKey(firstType.Item1)) sender.addByte(0x58);//POP EAX
20 | else if (sender.keywordMgr.getVarTypeByteSize(firstType.Item1)>resultB_Size) {
21 |
22 | sender.addByte(0x5A);//POP EDX
23 | sender.addBytes(new Byte[]{0x33,0xC0 });//XOR EAX,EAX
24 |
25 | if (resultB_Size==1)
26 | sender.addBytes(new Byte[]{0x8A,0xC2 });//mov al,dl
27 | else /*resultB_Size==2*/
28 | sender.addBytes(new Byte[]{0x66,0x8B,0xC2 });// mov ax,dx
29 |
30 | }
31 | else sender.addByte(0x58);//POP EAX
32 |
33 | this.outputType=secondType;
34 |
35 | return base.execute(sender, @params);
36 |
37 | }
38 |
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/Sunset/Keywords/KWConstant.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWConstant : Keyword {
5 |
6 | public const String constName="constant";
7 |
8 | public KWConstant () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.currentMods=sender.currentMods|Modifier.CONSTANT;
14 | sender.throwModErrIfInBlock();
15 | return base.execute(sender, @params);
16 |
17 | }
18 |
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWConstructor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/8/2021
5 | * Time: 5:20 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 | using Sunset.Stack;
13 |
14 | namespace Sunset.Keywords {
15 |
16 | public class KWConstructor : Keyword {
17 |
18 | public const String constName="constructor";
19 |
20 | public KWConstructor () : base (constName,KeywordType.NATIVE_CALL,true) { }
21 |
22 | public override KeywordResult execute(Parser sender,String[] @params) {
23 |
24 | if (sender.inFunction)
25 | throw new ParsingError("Tried to make a constructor inside of a function",sender);
26 |
27 | if (sender.constructor!=null)
28 | throw new ParsingError("Constructor already exists, and the \""+KWConstructor.constName+"\" keyword was called",sender);
29 |
30 | OpcodeIndexReference pos=sender.GetStaticInclusiveOpcodesCount(1);
31 | sender.addBytes(new Byte[]{0xE9,0,0,0,0});
32 | Byte[] newOpcodes=new Byte[0],endOpcodes=(@params.Length==0)?new Byte[]{0xC3}/*RET*/:new Byte[]{0xC2/*RET SHORT:(STACK RESTORATION AMOUNT)*/}.Concat(BitConverter.GetBytes((UInt16)(@params.Length*4))).ToArray();
33 |
34 | if (sender.addEsiToLocalAddresses)
35 | endOpcodes=new Byte[]{0x5E/*POP ESI*/}.Concat(endOpcodes).ToArray();
36 |
37 | Block constructorBlock=new Block(delegate {
38 | sender.inFunction=false;
39 | sender.inConstructor=false;
40 | if (sender.addEsiToLocalAddresses) sender.pseudoStack.pop();
41 | sender.pseudoStack.pop();
42 | sender.tryCreateRestoreEsiFunc();
43 | },sender.memAddress,endOpcodes,true);
44 |
45 | //For information on this, see KWNew -> Extra esi dword var on classes information
46 | if (sender.addEsiToLocalAddresses) {
47 | sender.addByte(0x56);//PUSH ESI
48 | sender.esiFuncReferences.Add(sender.getOpcodesCount()+1);
49 | sender.addBytes(new Byte[]{0xE8}.Concat(BitConverter.GetBytes(sender.memAddress))); //CALL DWORD RELATIVE ADDRESS
50 | }
51 |
52 | List>paramTypes=new List>();
53 | UInt16 paramIndex=0;
54 | foreach (String s in @params.Reverse())
55 | sender.pseudoStack.push(new LocalVar(s.Split(' ')[1]));
56 | foreach (String s in @params) {
57 |
58 | String[]split=s.Split(' ');
59 | if (split.Length!=2)
60 | throw new ParsingError("Invalid function declaration parameter: \""+s+'"',sender);
61 |
62 | String unparsedType=split[0],varName=split[1];
63 |
64 | TuplevarType=sender.getVarType(unparsedType);
65 | paramTypes.Add(varType);
66 | Console.WriteLine(varType.Item1+','+varType.Item2.ToString()+','+varName);
67 | constructorBlock.localVariables.Add(varName,new Tuple>(varType));
68 | ++paramIndex;
69 |
70 | }
71 | sender.pseudoStack.push(new ReturnPtr());
72 | if (sender.addEsiToLocalAddresses)
73 | sender.pseudoStack.push(new EsiPtr());
74 | sender.addBlock(constructorBlock,1);
75 | constructorBlock.blockMemPositions.Add(pos);
76 | sender.inFunction=true;
77 | sender.inConstructor=true;
78 | sender.constructor=new Tuple>>(constructorBlock.startMemAddr,paramTypes);
79 | return base.execute(sender, @params);
80 |
81 | }
82 |
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWContinue.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/21/2021
5 | * Time: 12:08 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset.Keywords {
14 |
15 | public class KWContinue : Keyword {
16 |
17 | public const String constName="continue";
18 |
19 | public KWContinue () : base (constName,KeywordType.NATIVE_CALL) { }
20 |
21 | public override KeywordResult execute (Parser sender,String[] @params) {
22 |
23 | if (sender.blocks.Count==0)
24 | throw new ParsingError("Can't continue outside of a block",sender);
25 | Block block=(sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Count()==0)?sender.blocks.Keys.Last():sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Last();
26 |
27 | sender.addByte(0xC9);
28 | ListnewOpcodes=new List(new Byte[]{0xE9});
29 | if (!(sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Count()==0)) {
30 |
31 | block=sender.blocks.Keys.Where(x=>x.isLoopOrSwitchBlock).Last();
32 | UInt32 bonusLeaves=(UInt32)(sender.blocks.Count-sender.blocks.Keys.Cast().ToList().IndexOf(block))-1;
33 | Byte[]leaves=new Byte[bonusLeaves];
34 | UInt32 i=0;
35 | while (i!=leaves.Length) {
36 |
37 | leaves[i]=0xC9;
38 | ++i;
39 |
40 | }
41 | sender.addBytes(leaves);
42 |
43 | }
44 |
45 | if (block.continueAddress==0)
46 | throw new ParsingError("Unexpected continue (its block does not support continue)",sender);
47 |
48 | if (block.continueInstructions!=null)
49 | newOpcodes.InsertRange(0,block.continueInstructions);
50 |
51 | return new KeywordResult(){newOpcodes=newOpcodes.Concat(BitConverter.GetBytes((Int32)block.continueAddress-(Int32)(sender.GetStaticInclusiveAddress()+newOpcodes.Count+4))).ToArray(),newStatus=ParsingStatus.SEARCHING_NAME};
52 |
53 | }
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWCrash.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/4/2021
5 | * Time: 7:16 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWCrash : Keyword {
14 |
15 | public const String constName="crash";
16 |
17 | public KWCrash () : base (constName,KeywordType.NATIVE_CALL) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | return new KeywordResult(){newOpcodes=new Byte[]{0xCC},newStatus= ParsingStatus.SEARCHING_NAME};
22 |
23 | }
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWDecrease.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/31/2021
5 | * Time: 12:42 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWDecrease : Keyword {
14 |
15 | public const String constName="--";
16 |
17 | public KWDecrease () : base (constName,KeywordType.DECREMENT) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | if (String.IsNullOrEmpty(sender.lastReferencedVariable))
22 | throw new ParsingError("Invalid use of \""+constName+"\", no referenced variable found",sender);
23 |
24 |
25 | Byte[] newOpcodes=new Byte[0];
26 |
27 | String varType=sender.getVariablesType(sender.lastReferencedVariable);
28 |
29 | //TODO:: make this work for more than native variables
30 | //HACK:: check variable type
31 | if (varType==KWByte.constName) {
32 |
33 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+2);
34 | newOpcodes=new Byte[]{0xFE,0x0D,0,0,0,0};
35 |
36 | }
37 | else if (varType==KWShort.constName) {
38 |
39 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+3);
40 | newOpcodes=new Byte[]{0x66,0xFF,0x0D,0,0,0,0};
41 |
42 | }
43 | else if (varType==KWInteger.constName) {
44 |
45 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+2);
46 | newOpcodes=new Byte[]{0xFF,0x0D,0,0,0,0};
47 |
48 |
49 | }
50 | else throw new ParsingError("Can't decrease variable type \""+varType+'"',sender);
51 |
52 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_NAME,newOpcodes=newOpcodes};
53 |
54 | }
55 |
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWDefault.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/6/2021
5 | * Time: 6:49 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWDefault : Keyword {
14 |
15 | public const String constName="default";
16 |
17 | public KWDefault () : base (constName,KeywordType.NATIVE_CALL) { }
18 |
19 | public override KeywordResult execute(Parser sender,String[]@params) {
20 |
21 | KWCase.checkForCaseFallThrough(sender);
22 | Block defaultBlock=new Block(null,sender.GetStaticInclusiveAddress(),new Byte[0]){caseOrDefaultBlock=true,hasParentheses=false};
23 | sender.addBlock(defaultBlock,0);
24 | return new KeywordResult(){newOpcodes=new Byte[0],newStatus=(sender.isColon(sender.nextChar)?ParsingStatus.SEARCHING_NAME:ParsingStatus.SEARCHING_COLON)};
25 |
26 | }
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWDllReference.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/8/2021
5 | * Time: 9:31 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset.Keywords {
14 |
15 | public class KWDllReference : Keyword {
16 |
17 | public const String constName="dllref";
18 |
19 | public KWDllReference () : base (constName,KeywordType.FUNCTION,true) { }
20 |
21 | public override KeywordResult execute (Parser sender,String[] @params) {
22 |
23 | if (@params.Length==0)
24 | throw new ParsingError("Expected 1 or more parameters for \""+constName+'"',sender);
25 |
26 | List>varTypes=new List>(@params.Length-1);
27 | foreach (String s in @params.Skip(1)) {
28 | Tuplevt=sender.getVarType(s);
29 | varTypes.Add(new ValueTuple(vt.Item1,vt.Item2));
30 | }
31 |
32 | sender.nextFunctionParamTypes=varTypes.ToArray();
33 | sender.nextType=FunctionType.DLL_REFERENCED;
34 | sender.nextReferencedDLL=@params[0];
35 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_FUNCTION_NAME,newOpcodes=new Byte[0]};
36 |
37 | }
38 |
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/Sunset/Keywords/KWElse.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/8/2021
5 | * Time: 9:31 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWElse : Keyword {
15 |
16 | public const String constName="else";
17 |
18 | public KWElse () : base (constName,KeywordType.NATIVE_CALL) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | //Sbyte Jump: 0xEB, (SByte)
23 | //Far Jump: 0xE9, (Signed Integer ,,,,)
24 | //DO NOTICE before changing the byte size of the jump opcodes take a look at Parser#elseBlockClosed
25 | sender.addBytes(new Byte[]{0xE9,0,0,0,0});//JMP TO MEM ADDR
26 | Int32 pOpcodes=sender.GetStaticInclusiveOpcodesCount().GetIndexAsInt();
27 | Block elseBlock=new Block(sender.elseBlockClosed,sender.GetStaticInclusiveAddress(),new Byte[0]);
28 | Block.pairBlocks(elseBlock,sender.lastBlockClosed);
29 | sender.addBlock(elseBlock);
30 | elseBlock.blockMemPositions.Add(sender.GetStaticInclusiveOpcodesCount(-4-(sender.GetStaticInclusiveOpcodesCount().GetIndexAsInt()-pOpcodes)));
31 | return base.execute(sender,@params);
32 |
33 | }
34 |
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWEnum.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/11/2021
5 | * Time: 2:34 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWEnum : Keyword {
14 |
15 | public const String constName="ENUM";
16 |
17 | public KWEnum () : base (constName,KeywordType.CLASS_TYPE_SETTER) { }
18 |
19 | public override KeywordResult execute(Parser sender,String[]@params) {
20 |
21 | if (sender.namesChked!=1)
22 | throw new ParsingError("Enum must be the first and only keyword of the file.",sender);
23 | sender.@enum=true;
24 |
25 | return base.execute(sender,@params);
26 |
27 | }
28 |
29 | }
30 |
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWExit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | namespace Sunset.Keywords {
4 |
5 | public class KWExit : Keyword {
6 |
7 | public const String constName="exit";
8 |
9 | public KWExit() : base (constName,KeywordType.NATIVE_CALL,true) { }
10 |
11 | public override KeywordResult execute (Parser sender,String[]@params) {
12 |
13 | Console.WriteLine(sender.pushValue(@params[0]).Item1+","+sender.pushValue(@params[0]).Item2.ToString());
14 | Console.ReadKey();
15 | return base.execute(sender,@params);
16 |
17 | }
18 |
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWExpectedTypes.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/8/2021
5 | * Time: 9:49 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Linq;
12 |
13 | namespace Sunset.Keywords {
14 |
15 | public class KWExpectedTypes : Keyword {
16 |
17 | public const String constName="EXPECTED_TYPES";
18 |
19 | public KWExpectedTypes () : base (constName,KeywordType.NATIVE_CALL,true) { }
20 |
21 | public override KeywordResult execute(Parser sender,String[] @params) {
22 |
23 | Keyword.throwIfShouldBeHeader(sender,constName);
24 | if (@params.Length==0)
25 | throw new ParsingError("Expected at least 1 parameter for \""+constName+'"',sender);
26 |
27 | if (sender.passedVarTypes==null)
28 | throw new ParsingError("Expected "+@params.Length+" passed types on class import, got none",sender);
29 |
30 | if (@params.Length!=sender.passedVarTypes.Count)
31 | throw new ParsingError("Expected "+@params.Length+" passed types on class import, got "+sender.passedVarTypes.Count+" ("+Parser.merge(sender.passedVarTypes.Select(x=>x.Item2.Item1),", ")+')',sender);
32 |
33 | UInt32 i=0;
34 | List>>list=new List>>();
35 | foreach (String s in @params) {
36 |
37 | if (sender.pvtContainsKey(s)) throw new ParsingError("In \""+constName+"\", got duplicate name \""+s+'"',sender);
38 | else if (sender.nameExists(s)) throw new ParsingError("Name already exists: \""+s+'"',sender);
39 | Tuple tpl=sender.passedVarTypes[(Int32)i].Item2;
40 | list.Add(new Tuple>(s,tpl));
41 | sender.keywordMgr.synonyms.Add(s,tpl.Item1);
42 | ++i;
43 |
44 | }
45 | sender.passedVarTypes=list;
46 |
47 | return base.execute(sender, @params);
48 |
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWFinishCompiling.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/5/2021
5 | * Time: 11:49 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWFinishCompiling : Keyword {
14 |
15 | public const String constName="FINISHCMP";
16 |
17 | public KWFinishCompiling () : base (constName,KeywordType.NATIVE_CALL) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | return new KeywordResult(){newOpcodes=new Byte[]{},newStatus= ParsingStatus.STOP_PARSING_IMMEDIATE};
22 |
23 | }
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWFunction.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/8/2021
5 | * Time: 2:22 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Linq;
12 | using Sunset.Stack;
13 |
14 | namespace Sunset.Keywords {
15 |
16 | // TODO:: look into Block->blockMemPositions, maybe add a function Block#addMemPosition that is static inclusive, same for blockRVAPositions and this.blockAddrBeforeAppendingReferences[block] and enterPositions etc.. (also every dictionary in Parser with a Block key)
17 |
18 | public class KWFunction : Keyword {
19 |
20 | public const String constName="func";
21 |
22 | public KWFunction () : base (constName,KeywordType.FUNCTION,true) { }
23 |
24 | public override KeywordResult execute (Parser sender,String[] @params) {
25 |
26 | if (sender.inFunction)
27 | throw new ParsingError("Tried to make a function inside of a function",sender);
28 |
29 | Modifier currentMods=sender.currentMods;
30 | sender.lastFuncOpcodeStartIndex=sender.getOpcodesCount();
31 | sender.lastFuncDataSectOpcodeStartIndex=(UInt32)Parser.dataSectBytes.Count();
32 | Boolean staticFunc=currentMods.HasFlag(Modifier.STATIC),shouldAddEsi=sender.addEsiToLocalAddresses&&!staticFunc;
33 | if (!staticFunc)
34 | sender.tryCreateRestoreEsiFunc();
35 |
36 | OpcodeIndexReference pos=sender.GetStaticInclusiveOpcodesCount(1);
37 | if (!staticFunc)
38 | sender.addBytes(new Byte[]{0xE9,0,0,0,0});
39 | // Byte[]newOpcodes=new Byte[]{0xE9,0,0,0,0}; //JMP TO MEM ADDR
40 | Byte[] newOpcodes=new Byte[0],endOpcodes=(@params.Length==0)?new Byte[]{0xC3}/*RET*/:new Byte[]{0xC2/*RET SHORT:(STACK RESTORATION AMOUNT)*/}.Concat(BitConverter.GetBytes((UInt16)(@params.Length*4))).ToArray();
41 |
42 | if (shouldAddEsi)
43 | endOpcodes=new Byte[]{0x5E/*POP ESI*/}.Concat(endOpcodes).ToArray();
44 |
45 | Block functionBlock=new Block(delegate{
46 | sender.inFunction=false;
47 | if(shouldAddEsi)
48 | sender.pseudoStack.pop();
49 | sender.pseudoStack.pop();
50 | },sender.GetStaticInclusiveAddress(currentMods.HasFlag(Modifier.STATIC)),endOpcodes,true);
51 |
52 | if (staticFunc) {
53 | functionBlock.afterBlockClosedFunc=delegate {
54 | sender.dwordsToIncByOpcodesUntilStaticFuncEnd.Clear();
55 | Parser.dataSectBytes.AddRange(sender.appendAfterStaticFunc);
56 | sender.appendAfterStaticFunc.Clear();
57 | };
58 | }
59 |
60 | //For information on this, see KWNew -> Extra esi dword var on classes information
61 | if (shouldAddEsi) {
62 | sender.addByte(0x56);//PUSH ESI
63 | sender.esiFuncReferences.Add(sender.getOpcodesCount()+1);
64 | sender.addBytes(new Byte[]{0xE8}.Concat(BitConverter.GetBytes(sender.memAddress))); //CALL DWORD RELATIVE ADDRESS
65 | }
66 |
67 | List>paramTypes=new List>();
68 | UInt16 paramIndex=0;
69 | foreach (String s in @params.Reverse()) {
70 | String[]pSP=s.Split(' ');
71 | if (pSP.Length!=2) throw new ParsingError("Expected function parameters declaration in (type, name) format",sender);
72 | sender.pseudoStack.push( new LocalVar(pSP[1]));
73 | }
74 | foreach (String s in @params) {
75 |
76 | String[]split=s.Split(' ');
77 | if (split.Length!=2)
78 | throw new ParsingError("Invalid function declaration parameter: \""+s+'"',sender);
79 |
80 | String unparsedType=split[0],varName=split[1];
81 |
82 | TuplevarType=sender.getVarType(unparsedType);
83 | paramTypes.Add(new ValueTuple(varType.Item1,varType.Item2));
84 | Console.WriteLine(varType.Item1+','+varType.Item2.ToString()+','+varName);
85 | functionBlock.localVariables.Add(varName,new Tuple>(varType));
86 | ++paramIndex;
87 |
88 | }
89 | sender.pseudoStack.push(new ReturnPtr());
90 | if (shouldAddEsi)
91 | sender.pseudoStack.push(new EsiPtr());
92 | sender.addBlock(functionBlock,0,staticFunc);
93 | if (!staticFunc)
94 | functionBlock.blockMemPositions.Add(pos);
95 | sender.inFunction=true;
96 | sender.nextFunctionParamsCount=(UInt16)@params.Length;
97 | sender.lastFunctionBlock=functionBlock;
98 |
99 | sender.nextFunctionParamTypes=paramTypes.ToArray();
100 |
101 | sender.nextType=FunctionType.SUNSET;
102 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_FUNCTION_NAME,newOpcodes=newOpcodes};
103 |
104 | }
105 |
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWGetProcessHeap.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/9/2021
5 | * Time: 5:11 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | ///
14 | /// Note, GetProcessHeap stores the process heap after it is retrieved for the first time (so re calling it isn't detrimental)
15 | ///
16 | public class KWGetProcessHeap : Keyword {
17 |
18 | public const String constName="getProcessHeap";
19 |
20 | public KWGetProcessHeap () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE) { }
21 |
22 | public override KeywordResult execute(Parser sender,String[] @params) {
23 |
24 | sender.pushProcessHeapVar();
25 | outputType=new Tuple(KWInteger.constName,VarType.NATIVE_VARIABLE);
26 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_NAME,newOpcodes=new Byte[]{0x58}/*POP EAX*/};
27 |
28 | }
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWGoto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | namespace Sunset.Keywords {
4 |
5 | public class KWGoto : Keyword {
6 |
7 | public const String constName="goto";
8 |
9 | public KWGoto () : base (constName,KeywordType.NATIVE_CALL,true) { }
10 |
11 | public override KeywordResult execute (Parser sender,String[]@params) {
12 |
13 | if (@params.Length!=1) throw new ParsingError("Expected 1 parameter (a label) for \""+constName+'"',sender);
14 |
15 | String labelName=@params[0];
16 | if (!(sender.labelReferences.ContainsKey(labelName)))
17 | sender.labelReferences.Add(labelName,new List>());
18 |
19 | KWGoto.leaveAllBlocks(sender);
20 | sender.labelReferences[labelName].Add(new Tuple(sender.getOpcodesCount()+1,sender.memAddress));
21 | sender.addBytes(new Byte[]{0xE9,0,0,0,0 });
22 |
23 | return base.execute(sender, @params);
24 |
25 | }
26 |
27 | public static void leaveAllBlocks (Parser sender) {
28 |
29 | foreach (Block b in sender.blocks.Keys) {
30 |
31 | sender.addByte(0xC9); //LEAVE
32 | if (b.breakInstructions!=null)
33 | sender.addBytes(b.breakInstructions);
34 |
35 | }
36 |
37 | }
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWIncrease.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/31/2021
5 | * Time: 12:42 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWIncrease : Keyword {
15 |
16 | public const String constName="++";
17 |
18 | public KWIncrease () : base (constName,KeywordType.INCREMENT) { }
19 |
20 | override public KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | if (String.IsNullOrEmpty(sender.lastReferencedVariable))
23 | throw new ParsingError("Invalid use of \""+constName+"\", no referenced variable found",sender);
24 |
25 | Byte[] newOpcodes=new Byte[0];
26 | if (sender.lastReferencedVariableIsLocal) {
27 |
28 | String varType=sender.getLocalVarHomeBlock(sender.lastReferencedVariable).localVariables[sender.lastReferencedVariable].Item1.Item1;
29 |
30 | if (varType==KWByte.constName) {
31 |
32 | if (sender.getLocalVarHomeBlock(sender.lastReferencedVariable)!=sender.getCurrentBlock())
33 | sender.localVarEBPPositionsToOffset[sender.getCurrentBlock()].Add(sender.getOpcodesCount()+2);
34 | sender.addBytes(new Byte[]{0xFE,0x45,sender.pseudoStack.getVarEbpOffset(sender.lastReferencedVariable)}); //INC BYTE [EBP+-OFFSET]
35 |
36 | }
37 | else if (varType==KWShort.constName) {
38 |
39 | if (sender.getLocalVarHomeBlock(sender.lastReferencedVariable)!=sender.getCurrentBlock())
40 | sender.localVarEBPPositionsToOffset[sender.getCurrentBlock()].Add(sender.getOpcodesCount()+3);
41 | sender.addBytes(new Byte[]{0x66,0xFE,0x45,sender.pseudoStack.getVarEbpOffset(sender.lastReferencedVariable)}); //INC WORD [EBP+-OFFSET]
42 |
43 |
44 | }
45 | else if (varType==KWInteger.constName) {
46 |
47 | if (sender.getLocalVarHomeBlock(sender.lastReferencedVariable)!=sender.getCurrentBlock())
48 | sender.localVarEBPPositionsToOffset[sender.getCurrentBlock()].Add(sender.getOpcodesCount()+2);
49 | sender.addBytes(new Byte[]{0xFF,0x45,sender.pseudoStack.getVarEbpOffset(sender.lastReferencedVariable)}); //INC DWORD [EBP+-OFFSET]
50 |
51 | }
52 |
53 | }
54 | else {
55 |
56 | String varType=sender.getVariablesType(sender.lastReferencedVariable);
57 |
58 | //TODO:: make this work for more than native variables & local variables (in whole file, but even here it can be for more than these, it can work for classes etc.)
59 | //HACK:: check variable type
60 | if (varType==KWByte.constName) {
61 | if (sender.addEsiToLocalAddresses) {
62 |
63 | newOpcodes=new Byte[]{0xFE,0x86}.Concat(BitConverter.GetBytes(sender.appendAfterIndex[sender.lastReferencedVariable])).ToArray();//INC BYTE[PTR+ESI]
64 |
65 | }
66 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+2);
67 | newOpcodes=new Byte[]{0xFE,5,0,0,0,0};
68 |
69 | }
70 | else if (varType==KWShort.constName) {
71 | if (sender.addEsiToLocalAddresses) {
72 |
73 | newOpcodes=new Byte[]{0x66,0xFF,0x86}.Concat(BitConverter.GetBytes(sender.appendAfterIndex[sender.lastReferencedVariable])).ToArray();//INC WORD[PTR+ESI]
74 |
75 | }
76 | else {
77 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+3);
78 | newOpcodes=new Byte[]{0x66,0xFF,5,0,0,0,0};
79 | }
80 |
81 |
82 | }
83 | else if (varType==KWInteger.constName) {
84 |
85 | if (sender.addEsiToLocalAddresses) {
86 |
87 | newOpcodes=new Byte[]{0xFF,0x86}.Concat(BitConverter.GetBytes(sender.appendAfterIndex[sender.lastReferencedVariable])).ToArray();//INC DWORD[PTR+ESI]
88 |
89 | }
90 | else {
91 |
92 | sender.variableReferences[sender.lastReferencedVariable].Add(sender.getOpcodesCount()+2);
93 | newOpcodes=new Byte[]{0xFF,5,0,0,0,0}; //INC DWORD [PTR]
94 |
95 | }
96 |
97 |
98 | }
99 | else throw new ParsingError("Can't increase variable type \""+varType+'"',sender);
100 |
101 | }
102 |
103 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_NAME,newOpcodes=newOpcodes};
104 |
105 | }
106 |
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWInherit.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/6/2021
5 | * Time: 6:49 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 | using System.Runtime.InteropServices;
13 | using Sunset.VarTypes;
14 |
15 | namespace Sunset.Keywords {
16 |
17 | public class KWInherit : Keyword {
18 |
19 | public const String constName="INHERIT";
20 |
21 | public KWInherit () : base (constName,KeywordType.NATIVE_CALL,true) { }
22 |
23 | public override KeywordResult execute(Parser sender,String[]@params) {
24 |
25 | Keyword.throwIfShouldBeHeader(sender,constName);
26 | if (@params.Length==0) throw new ParsingError("Expected params for \""+constName+"\", but got none",sender);
27 | if (sender.@struct) throw new ParsingError("Can't inherit classes as a struct",sender);
28 | foreach (String str in @params) {
29 | //.... get class that is referenced (throw parsingerror if non existant/non imported)
30 | if (sender.containsImportedClass(str)) {
31 | //.... copy static funcs
32 | //.... require non-private variables/arrays of parent to be defined
33 | //.... require non-private funcs of parent to be defined
34 | Class cl=sender.importedClasses.Where(x=>x.className==str).First();
35 | foreach(KeyValuePairkp in cl.functions.Where(x=>!x.Value.modifier.HasFlag(Modifier.PRIVATE)&&!x.Value.modifier.HasFlag(Modifier.STATIC))) {
36 | if (sender.inhFuncsToDefine.ContainsKey(kp.Key)) throw new ParsingError("Can't inherit \""+str+"\" because a function with name \""+kp.Key+"\" is already waiting to be inherited! (An inherited class is incompatible with another one because of duplicate/shared instance names)",sender);
37 | sender.inhFuncsToDefine.Add(kp.Key,kp.Value);
38 | }
39 | foreach(KeyValuePair>kp in cl.variables.Where(x=>!x.Value.Item3.HasFlag(Modifier.PRIVATE)&&!x.Value.Item3.HasFlag(Modifier.STATIC))) {
40 | if (sender.inhVarsToDefine.ContainsKey(kp.Key)) throw new ParsingError("Can't inherit \""+str+"\" because a variable with name \""+kp.Key+"\" is already waiting to be inherited! (An inherited class is incompatible with another one because of duplicate/shared instance names)",sender);
41 | sender.inhVarsToDefine.Add(kp.Key,kp.Value);
42 | }
43 | foreach(KeyValuePair>kp in cl.arrays.Where(x=>!x.Value.Item4.HasFlag(Modifier.PRIVATE)&&!x.Value.Item4.HasFlag(Modifier.STATIC))) {
44 | if (sender.inhArrsToDefine.ContainsKey(kp.Key)) throw new ParsingError("Can't inherit \""+str+"\" because an array with name \""+kp.Key+"\" is already waiting to be inherited! (An inherited class is incompatible with another one because of duplicate/shared instance names)",sender);
45 | sender.inhArrsToDefine.Add(kp.Key,kp.Value);
46 | }
47 | foreach(KeyValuePair> kp in cl.classes.Where(x=>!x.Value.Item4.HasFlag(Modifier.PRIVATE)&&!x.Value.Item4.HasFlag(Modifier.STATIC))) {
48 | if (sender.inhClassesToDefine.ContainsKey(kp.Key)) throw new ParsingError("Can't inherit \""+str+"\" because a class instance with name \""+kp.Key+"\" is already waiting to be inherited! (An inherited class is incompatible with another one because of duplicate/shared instance names)",sender);
49 | sender.inhClassesToDefine.Add(kp.Key,kp.Value);
50 | }
51 | sender.inheritedClasses.Add(cl);
52 |
53 | // Solution Idea:
54 | // at start of all classes, if (esi,=,0), set opcodeportionbytesize + inherittaaindex to ESI, then RETN
55 | // back at movClassItemAddrIntoEax, in func case, push esi,xor esi esi,call EAX,add EAX [EAX+ESI+fn.instanceId*4],pop esi
56 |
57 | } else throw new ParsingError("Class \""+str+"\" does not exist. Did you forget to import?",sender);
58 | }
59 |
60 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_NAME,newOpcodes=new Byte[0]};
61 |
62 |
63 | }
64 |
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWInteger.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:59 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWInteger : Keyword {
14 |
15 | public const String constName="int";
16 |
17 | public KWInteger () : base (constName,KeywordType.TYPE) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | sender.varType=this.name;
22 | sender.lastReferencedVarType=VarType.NATIVE_VARIABLE;
23 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
24 |
25 | }
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWLengthOf.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/11/2021
5 | * Time: 1:44 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWLengthOf : Keyword {
14 |
15 | public const String constName="lengthof";
16 |
17 | public KWLengthOf () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | if (@params.Length!=1)
22 | throw new ParsingError("Expected 1 array parameter for \""+constName+"\", got "+@params.Length.ToString()+" parameters",sender);
23 |
24 | VarType type=sender.pushValue(@params[0]).Item2;
25 | if (type!=VarType.NATIVE_ARRAY)
26 | throw new ParsingError("Expected an array as a parameter of \""+constName+"\", but got \""+type.ToString()+'"',sender);
27 |
28 | sender.addBytes(new Byte[]{0x8B,4,0x24}); //MOV EAX,[ESP]
29 | sender.addBytes(new Byte[]{0x8B,0}); //MOV EAX,[EAX]
30 | sender.addBytes(new Byte[]{0x83,0xC4,4}); //ADD ESP,4
31 | outputType=new Tuple(KWInteger.constName,VarType.NATIVE_VARIABLE);
32 |
33 | return base.execute(sender, @params);
34 |
35 | }
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWLocal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWLocal : Keyword {
5 |
6 | public const String constName="local";
7 |
8 | public KWLocal () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.currentMods.throwIfhasAccessorModifier(sender);
14 | sender.currentMods=sender.currentMods|Modifier.LOCAL;
15 | return base.execute(sender, @params);
16 |
17 | }
18 |
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWNofunc.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/4/2021
5 | * Time: 7:16 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWNofunc : Keyword {
14 |
15 | public const String constName="nofunct";
16 |
17 | public KWNofunc () : base (constName,KeywordType.NATIVE_CALL,true) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | if (@params.Length==1) {
22 |
23 | String param=@params[0];
24 | UInt32 i;
25 | if (UInt32.TryParse(param,out i)) {
26 | Byte[]n=new Byte[i];
27 | UInt32 i0=0;
28 | while (i0!=i) {
29 | n[i0]=0x90; //NOP
30 | ++i0;
31 | }
32 | return new KeywordResult(){newOpcodes=n,newStatus=ParsingStatus.SEARCHING_NAME};
33 | }
34 |
35 | switch (param) {
36 | case "DUMP_STACK_IMAGE":
37 | sender.pseudoStack.printStackDump();
38 | break;
39 | case "DUMP_STACK_IMAGE_READKEY":
40 | sender.pseudoStack.printStackDump(true);
41 | break;
42 | case "READKEY":
43 | Console.ReadKey(true);
44 | break;
45 | default:
46 | throw new ParsingError("Invalid compiler instruction for \""+constName+"\": \""+@params[0]+"\"",sender);
47 |
48 | }
49 |
50 | }
51 | else if (@params.Length!=0)
52 | throw new ParsingError("Expected 1 or 0 parameters for \""+constName+'"',sender);
53 |
54 |
55 | // Console.ReadKey();
56 | return new KeywordResult(){newOpcodes=new Byte[]{0x90},newStatus= ParsingStatus.SEARCHING_NAME};
57 |
58 | }
59 |
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWPrivate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWPrivate : Keyword {
5 |
6 | public const String constName="private";
7 |
8 | public KWPrivate () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.currentMods.throwIfhasAccessorModifier(sender);
14 | sender.throwModErrIfInBlock();
15 | sender.currentMods=sender.currentMods|Modifier.PRIVATE;
16 | return base.execute(sender, @params);
17 |
18 | }
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWPublic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWPublic : Keyword {
5 |
6 | public const String constName="public";
7 |
8 | public KWPublic () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.currentMods.throwIfhasAccessorModifier(sender);
14 | sender.throwModErrIfInBlock();
15 | sender.currentMods=sender.currentMods|Modifier.PUBLIC;
16 | return base.execute(sender, @params);
17 |
18 | }
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWPullable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWPullable : Keyword {
5 |
6 | public const String constName="pullable";
7 |
8 | public KWPullable () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.currentMods.throwIfhasAccessorModifier(sender);
14 | sender.throwModErrIfInBlock();
15 | sender.currentMods=sender.currentMods|Modifier.PULLABLE;
16 | return base.execute(sender, @params);
17 |
18 | }
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWReturn.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/8/2021
5 | * Time: 11:19 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWReturn : Keyword {
15 |
16 | public const String constName="retn";
17 |
18 | public KWReturn () : base (constName,KeywordType.NATIVE_CALL,true) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | if (@params.Length==0) {
23 |
24 | if (sender.inFunction&&sender.functions.Last().Value.returnType!=null)
25 | throw new ParsingError("Expected return value",sender);
26 |
27 | if (sender.inFunction) {
28 | exitBlocks(sender);
29 | sender.blockAddrBeforeAppendingReferences[sender.lastFunctionBlock].Add(new Tuple(sender.GetStaticInclusiveOpcodesCount().index+1,0));
30 | return new KeywordResult{newOpcodes=new Byte[]{0xE9,}.Concat(BitConverter.GetBytes((UInt32)(sender.GetStaticInclusiveAddress()+1))).ToArray(),newStatus=ParsingStatus.SEARCHING_NAME};
31 | }
32 | else {
33 | this.exitBlocks(sender);
34 | sender.freeHeapsRefs.Add(sender.getOpcodesCount()+1);
35 | // v--- this is +7 instead of +5 so that it will calculate to jump to not POP EAX and RETN but PUSH 0, POP EAX and RETN
36 | return new KeywordResult{newOpcodes=new Byte[]{0xE9}.Concat(BitConverter.GetBytes(sender.memAddress+7)).ToArray(), //JMP TO RELATIVE MEM ADDR
37 | newStatus=ParsingStatus.SEARCHING_NAME};
38 | }
39 |
40 | }
41 | else {
42 |
43 | if (@params.Length!=1)
44 | throw new ParsingError("Expected 1 or 0 parameters for \""+constName+'"',sender);
45 |
46 | TupleretType=sender.pushValue(@params[0]);
47 |
48 | if (!sender.inFunction) {
49 | // Console.ReadKey();
50 | sender.addByte(0x58); //POP EAX
51 | this.exitBlocks(sender);
52 | sender.freeHeapsRefs.Add(sender.getOpcodesCount()+1);
53 | return new KeywordResult{newOpcodes=new Byte[]{0xE9}.Concat(BitConverter.GetBytes(sender.memAddress+4)).ToArray(), //JMP TO RELATIVE MEM ADDR
54 | newStatus=ParsingStatus.SEARCHING_NAME};
55 | }
56 |
57 | sender.addByte(0x58); //POP EAX
58 |
59 | this.exitBlocks(sender);
60 |
61 | if (sender.functions.Last().Value.returnType==null)
62 | throw new ParsingError("Did not expect return value",sender);
63 |
64 | if ((sender.functions.Last().Value.returnType.Item2==VarType.NATIVE_VARIABLE&&retType.Item1!=KWString.constName)||sender.keywordMgr.getVarTypeByteSize(sender.functions.Last().Value.returnType.Item1)>=sender.keywordMgr.getVarTypeByteSize(retType.Item1))
65 | goto skipCheck;
66 |
67 | if (!sender.functions.Last().Value.returnType.Equals(retType))
68 | throw new ParsingError("Unexpected variable return type (Expected \""+sender.functions.Last().Value.returnType.Item1+"\" of \""+sender.functions.Last().Value.returnType.Item2+"\", yet the return value was \""+retType.Item1+"\" of \""+retType.Item2+"\")",sender);
69 |
70 | skipCheck:
71 |
72 | // sender.pseudoStack.printStackDump(true);
73 | sender.blockAddrBeforeAppendingReferences[sender.lastFunctionBlock].Add(new Tuple(sender.GetStaticInclusiveOpcodesCount().index+1,0));
74 | return new KeywordResult{newOpcodes=new Byte[]{0xE9}.Concat(BitConverter.GetBytes((UInt32)(sender.GetStaticInclusiveAddress()+1))).ToArray(),newStatus=ParsingStatus.SEARCHING_NAME};
75 |
76 | }
77 |
78 | }
79 |
80 | private void exitBlocks (Parser sender) {
81 |
82 | UInt16 blocksToExit=(UInt16)((sender.blocks.Count-sender.blocks.Keys.ToList().IndexOf(sender.lastFunctionBlock))-1);
83 | sender.addBytes(new Byte[blocksToExit].Select(x=>x=0xC9)); // LEAVE (* blocksToExit)
84 |
85 | }
86 |
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWSetOrigin.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: GDSPIOSJDGOSDHGJSDhg
4 | * Date: 9/10/2022
5 | * Time: 8:56 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using Sunset.Stack;
12 | using System.Collections.Generic;
13 |
14 | namespace Sunset.Keywords {
15 |
16 | public class KWSetOrigin : Keyword {
17 |
18 | public const String constName="setOrigin";
19 |
20 | public KWSetOrigin () : base (constName,KeywordType.NATIVE_CALL,true) { }
21 |
22 | public override KeywordResult execute (Parser sender,String[]@params) {
23 |
24 | if (@params.Length!=1) throw new ParsingError("Expected 1 param for keyword \""+constName+"\" got "+@params.Length.ToString(),sender);
25 |
26 | UInt32 newAddr;
27 | if (!UInt32.TryParse(@params[0],out newAddr))
28 | throw new ParsingError("Invalid origin: \""+@params[0]+"\" (should be a memory address)",sender);
29 |
30 | sender.memAddress=newAddr;
31 | return base.execute(sender,@params);
32 |
33 | }
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWSetProcessHeapVar.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/15/2021
5 | * Time: 1:48 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWSetProcessHeapVar : Keyword {
14 |
15 | public const String constName="setpheapvar";
16 |
17 | public KWSetProcessHeapVar () : base (constName,KeywordType.NATIVE_CALL) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[]@params) {
20 |
21 | sender.setProcessHeapVar();
22 | return base.execute(sender, @params);
23 |
24 | }
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWSetStyle.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: GDSPIOSJDGOSDHGJSDhg
4 | * Date: 9/10/2022
5 | * Time: 8:56 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using Sunset.Stack;
12 | using System.Collections.Generic;
13 |
14 | namespace Sunset.Keywords {
15 | ///
16 | /// Note, in Sunset, setStyle shouldn't ever get indented because it doesn't care about blocks, i.e:
17 | /// if (true) {
18 | /// do (this)
19 | /// ...
20 | /// setStyle(Array,Static)
21 | /// continueDoingThings(foo)
22 | /// yeee
23 | /// }
24 | ///
25 | public class KWSetStyle : Keyword {
26 |
27 | public const String constName="setStyle";
28 |
29 | public KWSetStyle () : base (constName,KeywordType.NATIVE_CALL,true) { }
30 |
31 | public override KeywordResult execute (Parser sender,String[]@params) {
32 |
33 | if (@params.Length!=2) throw new ParsingError("Expected 2 params for keyword \""+constName+"\" got "+@params.Length.ToString(),sender);
34 |
35 | if (@params[0].ToLower().Equals("array")) {
36 | switch (@params[1].ToLower()) {
37 | case "dynamic":
38 | case "heap":
39 | sender.style=ArrayStyle.DYNAMIC_MEMORY_HEAP;
40 | break;
41 | case "static":
42 | sender.style=ArrayStyle.STATIC_MEMORY_BLOCK;
43 | break;
44 | case "stackalloc":
45 | case "stack":
46 | sender.style=ArrayStyle.STACK_ALLOCATION;
47 | throw new ParsingError("Unimplemented",sender);//UNDONE:: do stack allocation array style. it will probably have to only exist within blocks
48 | //break;
49 | default:
50 | throw new ParsingError("Unexpected array style type in \""+constName+"\", expected \"dynamic\"/,\"heap\", \"static\", or \"stack\"/\"stackalloc\" but got \""+@params[1]+"\".",sender);
51 | }
52 | return base.execute(sender,@params);
53 | }
54 |
55 | throw new ParsingError("Unexpected style type in \""+constName+"\", expected \"array\", but got \""+@params[0]+"\".",sender);
56 |
57 | }
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWShort.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:59 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWShort : Keyword {
14 |
15 | public const String constName="shr";
16 |
17 | public KWShort () : base (constName,KeywordType.TYPE) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | sender.varType=this.name;
22 | sender.lastReferencedVarType=VarType.NATIVE_VARIABLE;
23 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
24 |
25 | }
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWSizeOf.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/11/2021
5 | * Time: 2:05 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWSizeOf : Keyword {
15 |
16 | public const String constName="sizeof";
17 |
18 | public KWSizeOf () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | if (@params.Length!=1)
23 | throw new ParsingError("Expected 1 parameter for \""+constName+"\", got "+@params.Length.ToString()+" parameters",sender);
24 |
25 | sender.addBytes(new Byte[]{0xB8}.Concat(BitConverter.GetBytes(sender.keywordMgr.getVarTypeByteSize(sender.pushValue(@params[0]).Item1)))); //MOV EAX,DWORD
26 | sender.addBytes(new Byte[]{0x83,0xC4,4}); //ADD ESP,4
27 | outputType=new Tuple(KWInteger.constName,VarType.NATIVE_VARIABLE);
28 |
29 | return base.execute(sender, @params);
30 |
31 | }
32 |
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWStatic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset.Keywords {
3 |
4 | public class KWStatic : Keyword {
5 |
6 | public const String constName="static";
7 |
8 | public KWStatic () : base(constName,KeywordType.MODIFIER) { }
9 |
10 | public override KeywordResult execute(Parser sender,String[]@params) {
11 |
12 | sender.nextExpectedKeywordTypes=new KeywordType[]{KeywordType.MODIFIER,KeywordType.TYPE,KeywordType.FUNCTION };
13 | sender.throwModErrIfInBlock();
14 | sender.currentMods=sender.currentMods|Modifier.STATIC;
15 | return base.execute(sender, @params);
16 |
17 | }
18 |
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWString.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:59 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWString : Keyword {
14 |
15 | public const String constName="str";
16 |
17 | public KWString () : base (constName,KeywordType.TYPE) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | sender.varType=this.name;
22 | sender.lastReferencedVarType=VarType.NATIVE_VARIABLE;
23 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
24 |
25 | }
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWStruct.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/11/2021
5 | * Time: 2:34 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWStruct : Keyword {
14 |
15 | public const String constName="STRUCT";
16 |
17 | public KWStruct () : base (constName,KeywordType.CLASS_TYPE_SETTER) { }
18 |
19 | public override KeywordResult execute(Parser sender,String[]@params) {
20 |
21 | Keyword.throwIfShouldBeHeader(sender,constName);
22 | if (sender.inheritedClasses.Count!=0) throw new ParsingError("Can't inherit classes as a struct",sender);
23 |
24 | sender.@struct=true;
25 | sender.style=ArrayStyle.STATIC_MEMORY_BLOCK;
26 | if (sender.tableAddrIndex!=0)
27 | sender.clearOpcodes();
28 |
29 | return base.execute(sender,@params);
30 |
31 | }
32 |
33 | }
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWSwitch.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/6/2021
5 | * Time: 6:07 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using Sunset.Stack;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWSwitch : Keyword {
15 |
16 | public const String constName="switch";
17 |
18 | public KWSwitch () : base (constName,KeywordType.NATIVE_CALL,true) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[]@params) {
21 |
22 | if (@params.Length!=1) throw new ParsingError("Expected 1 parameter for \""+constName+'"',sender);
23 |
24 | sender.pushValue(@params[0]);
25 | sender.pseudoStack.push(new SwitchVar());
26 | sender.addBlock(new Block(delegate{sender.pseudoStack.pop();},sender.GetStaticInclusiveAddress(),new Byte[0]/*ADD ESP,4*/){isLoopOrSwitchBlock=true,switchBlock=true,afterBlockClosedOpcodes=new Byte[]{0x83,0xC4,4}});
27 |
28 | return base.execute(sender,@params);
29 |
30 | }
31 |
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWToggleGui.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 7/10/2021
5 | * Time: 9:32 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWToggleGui : Keyword {
14 |
15 | public const String constName="TOGGLE_GUI";
16 |
17 | public KWToggleGui () : base (constName,KeywordType.NATIVE_CALL) { }
18 |
19 | public override KeywordResult execute (Parser sender,String[]@params) {
20 |
21 | Keyword.throwIfShouldBeHeader(sender,constName);
22 |
23 | sender.gui=!sender.gui;
24 | sender.toggledGui=true;
25 | return base.execute(sender,@params);
26 |
27 | }
28 |
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWTypeSizeOf.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 8/11/2021
5 | * Time: 2:05 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KWTypeSizeOf : Keyword {
15 |
16 | public const String constName="Tsizeof";
17 |
18 | public KWTypeSizeOf () : base (constName,KeywordType.NATIVE_CALL_WITH_RETURN_VALUE) { }
19 |
20 | public override KeywordResult execute (Parser sender,String[] @params) {
21 |
22 | if (@params.Length!=1)
23 | throw new ParsingError("Expected 1 parameter for \""+constName+"\", got "+@params.Length.ToString()+" parameters",sender);
24 |
25 | sender.addBytes(new Byte[]{0xB8}.Concat(BitConverter.GetBytes(sender.keywordMgr.getVarTypeByteSize(@params[0])))); //MOV EAX,DWORD
26 | outputType=new Tuple(KWInteger.constName,VarType.NATIVE_VARIABLE);
27 |
28 | return base.execute(sender, @params);
29 |
30 | }
31 |
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KWVoid.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:59 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class KWVoid : Keyword {
14 |
15 | public const String constName="void";
16 |
17 | public KWVoid () : base (constName,KeywordType.TYPE) { }
18 |
19 | override public KeywordResult execute (Parser sender,String[] @params) {
20 |
21 | sender.varType=this.name;
22 | sender.lastReferencedVarType=VarType.NONE;
23 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_VARIABLE_NAME,newOpcodes=new Byte[0]};
24 |
25 | }
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Sunset/Keywords/Keyword.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:56 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public class Keyword {
14 |
15 | public readonly String name;
16 | public readonly Boolean hasParameters;
17 | public readonly KeywordType type;
18 | internal TupleoutputType;
19 |
20 | public Keyword (String name,KeywordType type,Boolean hasParameters=false) {
21 |
22 | this.name=name;
23 | this.hasParameters=hasParameters;
24 | this.type=type;
25 |
26 | }
27 |
28 | public virtual KeywordResult execute (Parser sender,String[] @params) {
29 |
30 | return new KeywordResult(){newStatus=ParsingStatus.SEARCHING_NAME,newOpcodes=new Byte[0]};
31 |
32 | }
33 |
34 | public static void throwIfShouldBeHeader (Parser sender,String kwName) {
35 |
36 | if (sender.getOpcodesCount()==sender.tableFuncBytes.Length&&sender.tableAddrIndex!=0) return;
37 | if (sender.getOpcodesCount()!=0||sender.getAppendAfterCount()!=0)
38 | throw new ParsingError("The \""+kwName+"\" keyword was expected at the header (top, beginning) of your source file",sender);
39 |
40 | }
41 |
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KeywordMgr.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 3:56 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 |
12 | namespace Sunset.Keywords {
13 |
14 | public class KeywordMgr {
15 |
16 | private List keywords;
17 | public List classWords;
18 | public Dictionary synonyms;
19 | public Dictionary acknowledgements;
20 | private Parser sender;
21 |
22 | public KeywordMgr (Parser sender) {
23 |
24 | this.keywords=new List(new Keyword[] {
25 |
26 | new KWByte(),
27 | new KWBecomes(),
28 | new KWIncrease(),
29 | new KWDecrease(),
30 | new KWShort(),
31 | new KWInteger(),
32 | new KWCrash(),
33 | new KWNofunc(),
34 | new KWIf(),
35 | new KWElse(),
36 | new KWBoolean(),
37 | new KWFunction(),
38 | new KWReturn(),
39 | new KWString(),
40 | new KWDllReference(),
41 | new KWWhile(),
42 | new KWBreak(),
43 | new KWContinue(),
44 | new KWFinishCompiling(),
45 | new KWToggleGui(),
46 | new KWImport(),
47 | new KWStruct(),
48 | new KWNew(),
49 | new KWVoid(),
50 | new KWSetProcessHeapVar(),
51 | new KWForeach(),
52 | new KWCallptr(),
53 | new KWSwitch(),
54 | new KWCase(),
55 | new KWDefault(),
56 | new KWConstructor(),
57 | new KWExpectedTypes(),
58 | new KWGetProcessHeap(),
59 | new KWLengthOf(),
60 | new KWSizeOf(),
61 | new KWTypeSizeOf(),
62 | new KWAcknowledge(),
63 | new KWAs(),
64 | new KWCast(),
65 | new KWMultiForeach(),
66 | new KWGoto(),
67 | new KWPublic(),
68 | new KWLocal(),
69 | new KWPrivate(),
70 | new KWPullable(),
71 | new KWStatic(),
72 | new KWConstant(),
73 | new KWExit(),
74 | new KWByteSizeOf(),
75 | new KWInherit(),
76 | new KWEnum(),
77 | new KWSetStyle(),
78 | new KWSetOrigin()
79 |
80 | });
81 |
82 | this.classWords=new List();
83 | this.synonyms=new Dictionary();
84 | this.acknowledgements=new Dictionary();
85 | this.sender=sender;
86 |
87 | }
88 |
89 | /// De-referenced keyword list
90 | public Keyword[] getKeywords () {
91 |
92 | return keywords.ToArray();
93 |
94 | }
95 |
96 | public UInt32 getVarTypeByteSize (String varType) {
97 |
98 | //HACK:: check variable type
99 | if (varType==KWByte.constName||varType==KWBoolean.constName||varType==Parser.NULL_STR)
100 | return 1;
101 | else if (varType==KWShort.constName)
102 | return 2;
103 | else if (varType==KWInteger.constName||varType==KWString.constName||this.classWords.Contains(varType))
104 | return 4;
105 | else if (synonyms.ContainsKey(varType))
106 | return getVarTypeByteSize(synonyms[varType]);
107 | else if (acknowledgements.ContainsKey(varType))
108 | return getVarTypeByteSize(acknowledgements[varType]);
109 | else
110 | throw new Exception("(DEV) Invalid var type \""+varType+'"');
111 |
112 | }
113 |
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KeywordResult.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 4:02 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public struct KeywordResult {
14 |
15 | public ParsingStatus newStatus;
16 | public Byte[] newOpcodes;
17 | public Action action;
18 |
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Sunset/Keywords/KeywordType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/5/2021
5 | * Time: 1:46 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Keywords {
12 |
13 | public enum KeywordType {
14 |
15 | ASSIGNMENT,INCREMENT,DECREMENT,NATIVE_CALL,CALL,TYPE,CLASS_TYPE_SETTER,NATIVE_CALL_WITH_RETURN_VALUE,TYPE_DEFINITION,TYPE_DEFINITION_ASSIGNEMENT,MODIFIER,FUNCTION,NONE
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/Machine.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 4/3/2021
5 | * Time: 6:04 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum Machine : ushort /* ushort == UInt16 */ {
14 |
15 | Unknown,
16 | Alpha=388,
17 | Alpha64=644,
18 | AM33=467,
19 | Amd64=34404,
20 | Arm=448,
21 | Arm64=43620,
22 | ArmThumb2=452,
23 | Ebc=3772,
24 | I386=332,
25 | IA64=512,
26 | M32R=36929,
27 | MIPS1=614,
28 | MipsFpu=870,
29 | MipsFpu16=1126,
30 | PowerPC=496,
31 | PowerPCFP=497,
32 | SH3=418,
33 | SH3Dsp=419,
34 | SH3E=420,
35 | SH4=422,
36 | SH5=424,
37 | Thumb=450,
38 | Tricore=1312,
39 | WceMipsV2=361
40 |
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/Sunset/Modifier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset {
3 |
4 | [Flags]
5 | public enum Modifier : uint {
6 |
7 | NONE,
8 | CONSTANT,
9 | STATIC,
10 |
11 | PUBLIC=0x10,
12 | PRIVATE=0x100,
13 | LOCAL=0x1000,
14 | PULLABLE=0x10000,
15 |
16 | }
17 |
18 | public static class ModifierTools {
19 |
20 | public static Boolean hasAccessorModifier (this Modifier mod) { return mod>=Modifier.PUBLIC; }
21 |
22 | public static void throwIfhasAccessorModifier (this Modifier mod,Parser psr) {
23 |
24 | if (mod.hasAccessorModifier())
25 | throw new ParsingError("Can't add multiple accessor modifiers to an instance",psr);
26 |
27 | }
28 |
29 | public static void throwModErrIfInBlock (this Parser psr) {
30 |
31 | if (psr.blocks.Count!=0)
32 | throw new ParsingError("Can't place modifiers inside of a block",psr);
33 |
34 | }
35 |
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/Sunset/OpcodeIndexReference.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Sunset {
3 |
4 | public class OpcodeIndexReference {
5 |
6 | public UInt32 index;
7 | public OpcodeIndexType type;
8 |
9 | private OpcodeIndexReference (UInt32 index,OpcodeIndexType type) {
10 |
11 | this.index=index;
12 | this.type=type;
13 |
14 | }
15 |
16 | public Int32 GetIndexAsInt () { return (Int32)index; }
17 |
18 | public static OpcodeIndexReference NewCodeSectRef (UInt32 index) { return new OpcodeIndexReference(index,OpcodeIndexType.CODE_SECT_REFERENCE); }
19 | public static OpcodeIndexReference NewDataSectRef (UInt32 index) { return new OpcodeIndexReference(index,OpcodeIndexType.DATA_SECT_REFERENCE); }
20 |
21 | }
22 |
23 |
24 | }
--------------------------------------------------------------------------------
/Sunset/OpcodeIndexType.cs:
--------------------------------------------------------------------------------
1 | namespace Sunset {
2 |
3 | public enum OpcodeIndexType {
4 |
5 | DATA_SECT_REFERENCE,
6 | CODE_SECT_REFERENCE
7 |
8 | }
9 |
10 |
11 | }
--------------------------------------------------------------------------------
/Sunset/ParsingError.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/30/2021
5 | * Time: 4:06 AM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Linq;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset {
14 |
15 | public class ParsingError : Exception {
16 |
17 | public ParsingError (String message,Parser sender) : base (
18 | '\n'+message+"\n\n"+
19 | ((sender==null)?"":
20 | "Class: "+sender.className+'\n'+
21 | "Path: "+sender.fileName+'\n'+
22 | ((sender.charCtrNegOneParsErr())?"":
23 | "\nLine: "+(sender.lastDataToParse.Substring(0,sender.charCtr).Where(x=>x=='\n').Count()+1).ToString()+", Char: "+sender.charCtr.ToString()+'\n'+
24 | "At: "+String.Concat(sender.lastDataToParse.Substring(sender.lastDataToParse.Substring(0,sender.charCtr).LastIndexOf('\n')+1).TakeUntil(x=>x=='\n')).Replace("\r","").Replace("\t","")+'\n'+
25 | String.Concat(new Char[sender.charCtr-(sender.lastDataToParse.Substring(0,sender.charCtr).LastIndexOf('\n')+1)+2])+"^\n"+
26 | String.Concat(new Char[sender.charCtr-(sender.lastDataToParse.Substring(0,sender.charCtr).LastIndexOf('\n')+1)+2])+'|'))
27 | ) { }
28 |
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Sunset/ParsingStatus.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 5/29/2021
5 | * Time: 11:39 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum ParsingStatus {
14 |
15 | SEARCHING_NAME,READING_NAME,
16 | SEARCHING_VARIABLE_NAME,READING_VARIABLE_NAME,
17 | SEARCHING_VALUE,READING_VALUE,
18 | SEARCHING_ARRAY_NAME,READING_ARRAY_NAME,
19 | READING_ARRAY_INDEXER,
20 | SEARCHING_PARAMETERS,READING_PARAMETERS,
21 | SEARCHING_FUNCTION_NAME,READING_FUNCTION_NAME,
22 | SEARCHING_TYPE_DEFINITION_NAME,READING_TYPE_DEFINITION_NAME,
23 | IN_COMMENT,
24 | STOP_PARSING_IMMEDIATE,
25 | READING_LABEL,
26 | SEARCHING_COLON
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/Sunset/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region Using directives
2 |
3 | using System;
4 | using System.Reflection;
5 | using System.Runtime.InteropServices;
6 |
7 | #endregion
8 |
9 | // General Information about an assembly is controlled through the following
10 | // set of attributes. Change these attribute values to modify the information
11 | // associated with an assembly.
12 | [assembly: AssemblyTitle("Sunset")]
13 | [assembly: AssemblyDescription("")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("")]
16 | [assembly: AssemblyProduct("Sunset")]
17 | [assembly: AssemblyCopyright("Copyright 2021")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // This sets the default COM visibility of types in the assembly to invisible.
22 | // If you need to expose a type to COM, use [ComVisible(true)] on that type.
23 | [assembly: ComVisible(false)]
24 |
25 | // The assembly version has following format :
26 | //
27 | // Major.Minor.Build.Revision
28 | //
29 | // You can specify all the values or you can use the default the Revision and
30 | // Build Numbers by using the '*' as shown below:
31 | [assembly: AssemblyVersion("1.0.*")]
32 |
--------------------------------------------------------------------------------
/Sunset/Stack/EsiPtr.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:38 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class EsiPtr : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public EsiPtr () { type=ItemType.ESI_PTR; }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Stack/IPseudoStackItem.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:25 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public interface IPseudoStackItem { ItemType type { set; get; } }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Sunset/Stack/ItemType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:26 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public enum ItemType {
14 |
15 | LOCAL_VAR,PRESERVED_EBP,RETURN_PTR,ESI_PTR,PRESERVED_ECX,SWITCH_VAR
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/Stack/LocalVar.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:31 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class LocalVar : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public readonly String varName;
17 | public LocalVar (String varName) {
18 | this.varName=varName;
19 | type=ItemType.LOCAL_VAR;
20 | }
21 |
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/Sunset/Stack/PreservedEBP.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:35 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class PreservedEBP : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public PreservedEBP () { this.type=ItemType.PRESERVED_EBP; }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Stack/PreservedECX.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:35 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class PreservedECX : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public PreservedECX () { this.type=ItemType.PRESERVED_ECX; }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Stack/PseudoStack.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:21 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Linq;
12 |
13 | namespace Sunset.Stack {
14 |
15 | public class PseudoStack {
16 |
17 | private List items;
18 |
19 | public PseudoStack () { items=new List(); }
20 |
21 | public void push (IPseudoStackItem item) {
22 |
23 | this.items.Add(item);
24 |
25 | }
26 |
27 | public void pop (UInt16 pops=1) {
28 |
29 | while (pops!=0) {
30 |
31 | this.items.RemoveAt(this.items.Count-1);
32 | --pops;
33 |
34 | }
35 |
36 | }
37 |
38 | public Byte getVarEbpOffset (String varName) {
39 |
40 | Int32 topEbpIndex=items.FindLastIndex(x=>x.type==ItemType.PRESERVED_EBP)
41 | ,varIndex=items.IndexOf(items.Where(x=>x.type==ItemType.LOCAL_VAR&&((LocalVar)x).varName==varName).First());
42 |
43 | return unchecked((Byte)((SByte)((topEbpIndex-varIndex)*4)));
44 |
45 | }
46 |
47 | public Byte getLatestEsiOffset () {
48 |
49 | Int32 topEbpIndex=items.FindLastIndex(x=>x.type==ItemType.PRESERVED_EBP)
50 | ,esiIndex=items.FindLastIndex(x=>x.type==ItemType.ESI_PTR);
51 |
52 | return unchecked((Byte)((SByte)((topEbpIndex-esiIndex)*4)));
53 |
54 | }
55 |
56 | public Byte getLatestSwitchVarOffset () {
57 |
58 | Int32 topEbpIndex=items.FindLastIndex(x=>x.type==ItemType.PRESERVED_EBP)
59 | ,svIndex=items.FindLastIndex(x=>x.type==ItemType.SWITCH_VAR);
60 |
61 | return unchecked((Byte)((SByte)((topEbpIndex-svIndex)*4)));
62 |
63 | }
64 |
65 | public void printStackDump (Boolean readKey=false) {
66 |
67 | Console.Write("\n\n== Stack ==\nTotal # of items: "+this.items.Count.ToString()+"\n\n");
68 |
69 | UInt16 i=0;
70 | foreach (IPseudoStackItem stackItem in this.items.ToArray().Reverse()) {
71 |
72 | switch (stackItem.type) {
73 |
74 | case ItemType.LOCAL_VAR:
75 | String varName=((LocalVar)stackItem).varName;
76 | Byte offset=this.getVarEbpOffset(varName);
77 | Console.WriteLine("Item #"+i.ToString()+": Local var \""+varName+"\", list index: "+this.items.IndexOf(stackItem).ToString()+", current EBP offset: "+offset.ToString("X").PadLeft(2,'0')+"h ("+unchecked((SByte)offset).ToString()+".)");
78 | break;
79 | case ItemType.PRESERVED_EBP:
80 | Console.WriteLine("Item #"+i.ToString()+": Preserved EBP ptr, list index: "+this.items.IndexOf(stackItem).ToString());
81 | break;
82 | case ItemType.RETURN_PTR:
83 | Console.WriteLine("Item #"+i.ToString()+": Call return ptr, list index: "+this.items.IndexOf(stackItem).ToString());
84 | break;
85 | case ItemType.ESI_PTR:
86 | Console.WriteLine("Item #"+i.ToString()+": Esi ptr, list index: "+this.items.IndexOf(stackItem).ToString());
87 | break;
88 | case ItemType.PRESERVED_ECX:
89 | Console.WriteLine("Item #"+i.ToString()+": Preserved ECX value, list index: "+this.items.IndexOf(stackItem).ToString());
90 | break;
91 | case ItemType.SWITCH_VAR:
92 | Console.WriteLine("Item #"+i.ToString()+": Switch block var, list index: "+this.items.IndexOf(stackItem).ToString());
93 | break;
94 | }
95 | ++i;
96 |
97 | }
98 |
99 | Console.Write("\n\n===========\n\n");
100 |
101 | if (readKey)
102 | if (Console.ReadKey(true).Key==ConsoleKey.Escape)throw new Exception();
103 |
104 | }
105 |
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/Sunset/Stack/ReturnPtr.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:38 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class ReturnPtr : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public ReturnPtr () { type=ItemType.RETURN_PTR; }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Stack/SwitchVar.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/17/2021
5 | * Time: 12:31 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset.Stack {
12 |
13 | public class SwitchVar : IPseudoStackItem {
14 |
15 | public ItemType type { set; get; }
16 | public SwitchVar () { this.type=ItemType.SWITCH_VAR; }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Sunset/Sunset.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | # SharpDevelop 4.4
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sunset", "Sunset.csproj", "{19D2E25E-77E6-443C-B6EB-2E58499E4104}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Release|Any CPU.Build.0 = Release|Any CPU
16 | {19D2E25E-77E6-443C-B6EB-2E58499E4104}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | EndGlobalSection
18 | EndGlobal
19 |
--------------------------------------------------------------------------------
/Sunset/SunsetProject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Linq;
4 | using System.IO;
5 | using System.Collections.Generic;
6 | namespace Sunset {
7 |
8 | public struct SunsetProject {
9 |
10 | public String name,mainFn,projPath;
11 |
12 | }
13 |
14 | public static class SunsetProjectHelper {
15 |
16 | private const Byte signature=18;
17 |
18 | public static SunsetProject LoadProject (String fn) {
19 |
20 | if (!File.Exists(fn))
21 | throw new InvalidProjectError("file \""+fn+"\" does not exist");
22 |
23 | Byte[]data=File.ReadAllBytes(fn);
24 |
25 | if (data.First()!=signature)
26 | ThrowCorrupted(fn);
27 |
28 | SunsetProject sp=new SunsetProject();
29 | Listlb=new List();
30 | Byte ctr=0;
31 | foreach (Byte b in data.Skip(1)) {
32 |
33 | if (b==0) {
34 | if (ctr==0) sp.name=Encoding.ASCII.GetString(lb.ToArray());
35 | else if (ctr==1) sp.mainFn=Encoding.ASCII.GetString(lb.ToArray());
36 | else ThrowCorrupted(fn);
37 | lb.Clear();
38 | ++ctr;
39 | }
40 | else lb.Add(b);
41 |
42 | }
43 |
44 | return sp;
45 |
46 | }
47 |
48 | private static void ThrowCorrupted (String fn) {
49 |
50 | throw new InvalidProjectError("file \""+fn+"\" is in invalid format or corrupted");
51 |
52 | }
53 |
54 | public static Byte[] ToBytes (this SunsetProject sp) {
55 |
56 | return new Byte[]{signature }.Concat(Encoding.ASCII.GetBytes(sp.name)).Concat(new Byte[1]).Concat(Encoding.ASCII.GetBytes(sp.mainFn)).Concat(new Byte[1]).ToArray();
57 |
58 | }
59 |
60 | }
61 |
62 | public class InvalidProjectError : Exception {
63 |
64 | public InvalidProjectError (String msg) : base ("Invalid sunset project: "+msg) { }
65 |
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Sunset/VarType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Elite
4 | * Date: 6/5/2021
5 | * Time: 2:58 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 |
11 | namespace Sunset {
12 |
13 | public enum VarType {
14 |
15 | NATIVE_VARIABLE,NATIVE_ARRAY,NATIVE_ARRAY_INDEXER,CLASS,FUNCTION,ENUM,NONE
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Sunset/VarTypes/Function.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: usr
4 | * Date: 2022-08-18
5 | * Time: 7:11 PM
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Runtime.InteropServices;
11 | using System.Collections.Generic;
12 |
13 | namespace Sunset.VarTypes {
14 |
15 | public struct Function {
16 |
17 | public UInt32 memAddr,instanceID;
18 | public TuplereturnType;
19 | public UInt16 expectedParameterCount;
20 | public FunctionType functionType;
21 | public CallingConvention callingConvention;
22 | public Modifier modifier;
23 | public List>parameterTypes;
24 | public Boolean isInherited;
25 |
26 | public Function (UInt32 memAddr,TuplereturnType,UInt16 expectedParameterCount,FunctionType funcType,CallingConvention callingConvention,Modifier modifier,List>paramTypes,UInt32 instanceId,Boolean inherited) {
27 | this.memAddr=memAddr;
28 | this.returnType=returnType;
29 | this.expectedParameterCount=expectedParameterCount;
30 | this.functionType=funcType;
31 | this.callingConvention=callingConvention;
32 | this.modifier=modifier;
33 | this.parameterTypes=paramTypes;
34 | this.isInherited=inherited;
35 | this.instanceID=instanceId;
36 | }
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/Sunset/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/ASCIIKey.sunset:
--------------------------------------------------------------------------------
1 | ENUM NULLCHAR,START_OF_HEADING,START_OF_TEXT,END_OF_TEXT,END_OF_TRANSMISSION,ENQUIRY,ACKNOWLEDGE,BELL,BACKSPACE,HORIZONTAL_TAB,LINE_FEED,VERTICAL_TAB,FORM_FEED,CARRIAGE_RETURN,SHIFT_OUT,SHIFT_IN,DATA_LINK_ESCAPE,DEVICE_CONTROL_ONE,DEVICE_CONTROL_TWO,DEVICE_CONTROL_THREE,DEVICE_CONTROL_FOUR,NEGATIVE_ACKNOWLEDGE,SYNCHRONOUS_IDLE,END_OF_TRANSMISSION_BLOCK,CANCEL,END_OF_MEDIUM,SUBSTITUTE,ESCAPE,FILE_SEPARATOR,GROUP_SEPARATOR,
2 | RECORD_SEPARATOR,UNIT_SEPARATOR,SPACE,EXLAMATION_MARK,DOUBLE_QUOTE,NUMBER_SIGN,DOLLAR_SIGN,PERCENT_SIGN,AMPERSAND,SINGLE_QUOTE,LEFT_FACING_PARENTHESIS,RIGHT_FACING_PARENTHESIS,ASTERISK,PLUS,COMMA,SUBTRACT,PERIOD,FORWARD_SLASH,ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,COLON,SEMI_COLON,LESS_THAN_SIGN,EQUALS_SIGN,GREATER_THAN_SIGN,QUESTION_MARK,AT_SIGN,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
3 | LEFT_FACING_SQUARE_BRACKET,BACKSLASH,RIGHT_FACING_SQUARE_BRACKET,CARET,UNDERSCORE,GRAVE,a,b,c,d,e,f,g,h,i,j,k,l,ma,n,o,p,q,r,s,t,u,v,w,x,y,z,LEFT_FACING_BRACE,VERTICAL_BAR,RIGHT_FACING_BRACE,SWUNG_DASH
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Capture.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Debug/Capture.PNG
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Color.sunset:
--------------------------------------------------------------------------------
1 | byte r
2 | byte g
3 | byte b
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Dictionary.sunset:
--------------------------------------------------------------------------------
1 | ; Untested
2 |
3 | EXPECTED_TYPES(T,T0)
4 | import(Tuple)
5 | import(List>)
6 |
7 | private List> entries becomes new(List>)
8 |
9 | public func(T key,T0 value) add {
10 | Tuple tuple becomes new(Tuple)
11 | tuple.item becomes key
12 | tuple.item0 becomes value
13 | entries.add(tuple)
14 | }
15 |
16 | public func(T key) find T0 {
17 | foreach (tuple,entries.toArray) {
18 | if (tuple.item,=,key) { retn(tuple.item0) }
19 | }
20 | retn(null)
21 | }
22 |
23 | public func clear { entries.clear }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Acknowledge Keyword.txt:
--------------------------------------------------------------------------------
1 | ; The acknowledge keyword simply creates a synonym for an already existing variable type
2 | ; It is paired with the "as" keyword
3 | ; i.e:
4 | acknowledge INTEGER as int
5 | acknowledge TEST as INTEGER
6 | ; There are default acknowledgements:
7 | ; PTR as int
8 | ; FUNCPTR as int
9 |
10 | ; With the previous acknowledgement in this file, the following lines can be written:
11 | INTEGER myNum becomes 34
12 |
13 | ; myNum functions as an int:
14 | myNum becomes myNum+4
15 |
16 | ; However, acknowledgements can not be converted from directly, they must be casted:
17 |
18 | TEST i becomes cast(myNum,TEST)
19 |
20 | func(int i) feedback int { retn(i+5) }
21 |
22 | myNum becomes feedback(cast(myNum,int))
23 |
24 | ; A reasonable way to cast it would be as such:
25 | int myNum0 becomes cast(myNum,int)
26 | ; ... and use myNum0 as an int
27 | ; Though, casting generally is not used so often for the one variable, and
28 | ; if it is, a revision might be necessary in many cases.
29 |
30 | ; Acknowledgements are passed down to the next class when a class with acknowledgements is imported.
31 |
32 | retn(myNum0)
33 |
34 | ; Should expect exit code: 34.+4+5=43.
35 | ; Got exit code: 43. (2Bh)
36 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Callptr keyword.txt:
--------------------------------------------------------------------------------
1 | ;This is an unsafe keyword because it requires the parameters to be their expected values,
2 | ;though there are no restrictions (as the compiler doesn't know any)
3 | ;It also returns an unsigned integer as the compiler also can't know the return value from a PTR,
4 | ;however that can be converted/used as any 4 byte var types such as classes or arrays.
5 | func(int i) test int {
6 |
7 | retn(i)
8 |
9 | }
10 |
11 | retn(callptr($test,123))
12 |
13 | ; Result:
14 | ; Exit code 7B (123.)
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Constructor Demo/MyClass.sunset:
--------------------------------------------------------------------------------
1 | int i
2 | func getResult int {
3 |
4 | retn(i)
5 |
6 | }
7 | constructor(int j,int k) {
8 |
9 | i becomes j*k
10 |
11 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Constructor Demo/source.txt:
--------------------------------------------------------------------------------
1 | import(Documentation\Constructor Demo\MyClass)
2 | dllref(User32,int,str,str,int) MessageBoxA int
3 | dllref(User32,str,str,int) cdecl:wsprintfA int
4 | MyClass mc becomes new(MyClass,3,4)
5 | str buffer becomes "##"
6 | wsprintfA(buffer,"%d",mc.getResult)
7 | MessageBoxA(0,buffer,"",0)
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Dll Referencing.txt:
--------------------------------------------------------------------------------
1 | ; Reference DLLs for displaying a message box, finding the handle (ptr) of a window & showing or hiding the window, respectively
2 | dllref(User32,int,str,str,int) MessageBoxA int
3 | dllref(User32,str,str) FindWindowA int
4 | dllref(User32,int,int) ShowWindow bool
5 |
6 | ;Notice: When referencing a function of which has a calling convention other than stdcall, use this format:
7 | ;dllref(User32,str,str,int) cdecl:wsprintfA int
8 |
9 | int ollyHandle becomes FindWindowA("OLLYDBG",null) ; Handle for x86 (x32) OllyDbg, can be set to any window if the className is found using WinSpy, Spy++, logical thinking, etc.
10 | bool pBool becomes false ; This is a boolean indicating whether or not the window was last visible
11 | ; Do notice that if the window is initially hidden, pBool should start off by being set to true. This is however generally an unlikely scenario
12 |
13 | ; Define a function without parameters or a return value
14 | func toggleWindowPerpetually {
15 |
16 | ; If the window is hidden
17 | if (pBool) {
18 |
19 | ; Show the window and tell the user so in the form of a MessageBox
20 | ; set pBool to the return value of ShowWindow which is true if previously visible, and vice versa
21 | pBool becomes ShowWindow(ollyHandle,1)
22 | MessageBoxA(0,"Shown the window","Hello",0)
23 |
24 | }
25 |
26 | ; If the window is not hidden
27 | else {
28 |
29 | ; Hide the window
30 | pBool becomes ShowWindow(ollyHandle,0)
31 | MessageBoxA(0,"Hid the window","Hello",0)
32 |
33 | }
34 |
35 | ; Perpetual recursion loop
36 | toggleWindowPerpetually
37 |
38 | }
39 |
40 | ; Call the primary function of this exemplar
41 | toggleWindowPerpetually
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Exit.txt:
--------------------------------------------------------------------------------
1 | dllref(User32,int,str,str,int) MessageBoxA int
2 | int i becomes 3
3 | int i0 becomes 4
4 | int i1 becomes 23
5 | :restart
6 | while (true) {
7 | while (i,=/=,7) {
8 | while (i0,=/=,30) {
9 | ++i0 ++i1
10 | if (i1,=,24) { exit } ; Exit with no parameters will break all loops
11 | if (i0,=,6) { exit(2) } ; Exit with parameters will break N(#) loops
12 | }
13 | ++i
14 | MessageBoxA(0,"After ++i","",0)
15 | }
16 | MessageBoxA(0,"End of while(true) loop","",0)
17 | retn
18 | }
19 | MessageBoxA(0,"End of blocks,"",0)
20 | goto(restart)
21 |
22 | ; ------------------
23 |
24 | ; Expected Result:
25 |
26 | ; 0: "End of blocks"
27 | ; 1: "End of while(true) loop"
28 | ; 2: Application terminated
29 |
30 | ; Reality:
31 |
32 | ;
33 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Foreach loops.txt:
--------------------------------------------------------------------------------
1 | dllref(User32,str,str,int) cdecl:wsprintfA int
2 | dllref(User32,int,str,str,int) MessageBoxA int
3 |
4 | str format becomes "%d"
5 | str buffer becomes "00"
6 | str empty becomes ""
7 |
8 | int# arr becomes #4
9 | arr[0] becomes 12
10 | arr[1] becomes 22
11 | arr[2] becomes 32
12 | arr[3] becomes 42
13 | foreach (item,arr) {
14 |
15 | if (item,=/=,0) {
16 |
17 | if (item,=,32) { break }
18 |
19 | wsprintfA(buffer,format,item)
20 | MessageBoxA(0,buffer,empty,0)
21 |
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Form Demo/source.txt:
--------------------------------------------------------------------------------
1 | import(Windows\Form)
2 | import(Windows\SimpleLabel)
3 | import(Windows\FormEventArgs)
4 | import(Windows\MessageBox)
5 | setpheapvar
6 |
7 | func(FormEventArgs args) formClosing {
8 |
9 | MessageBox mb becomes new(MessageBox)
10 | mb.mbox(args.info,"Form is closing")
11 |
12 | }
13 |
14 | func(FormEventArgs args) formOpening {
15 |
16 | MessageBox mb becomes new(MessageBox)
17 | mb.mbox(args.info,"Form is opening")
18 |
19 | }
20 |
21 | Form form becomes new(Form,"My Form",100,100,400,360)
22 |
23 | SimpleLabel lbl becomes new(SimpleLabel)
24 | SimpleLabel lbl0 becomes new(SimpleLabel)
25 |
26 | lbl.text becomes "Yo"
27 | lbl.x becomes 10
28 | lbl.y becomes 10
29 | lbl0.text becomes "My name joe"
30 | lbl0.x becomes 10
31 | lbl0.y becomes 200
32 |
33 | form.addComponent(lbl)
34 | form.addComponent(lbl0)
35 |
36 | form.onFormClosing.addFunction($formClosing)
37 | form.onFormCreation.addFunction($formOpening)
38 |
39 | form.show
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/In-line Math Test Source.txt:
--------------------------------------------------------------------------------
1 | func(int i) g int { retn(i) }
2 |
3 | int# nums becomes #7
4 | nums[0] becomes 1
5 | nums[1] becomes 2
6 | nums[2] becomes 3
7 | nums[5] becomes 1
8 | nums[6] becomes 2
9 |
10 | int oop becomes 3+6*4/2+3*6-4 ;29 (1Dh)
11 | int oop0 becomes 3+4+3/2/1*6+3+4+5+6*3-4-5+6/3 ;27h (but data gets lost when rounded so 24h)
12 | int oop1 becomes (3+4+3+6/2)+3*6-2+4-4/2 ;1Fh
13 | int oop45132 becomes 10/(19/3-4) ;5
14 | int oop2 becomes (3+4+5+6+7+8*4)*4-200/(6*4+3) ;Something like 0DCh (actually 0DDh because of rounded value)
15 | int test becomes (3+((3*4)+(3*2))+((3*3)+(4*9))-4) ; 62 (3Eh)
16 |
17 | int num becomes nums[0]+nums[nums[0]]+nums[nums[0]+nums[1]-1]/3 ; 4
18 | int num0 becomes 1*2*3*4*5*num+16 ; 496 (1F0h)
19 | int num1 becomes (1*4)+(num*6) ; (1*4)+(4*6) , 4+24, 28 (1Ch)
20 | int num2 becomes 3+((1*3*num)*3)+(num*4) ; 3+((1*3*4)*3)+(4*4), 55 (37h)
21 | int num3 becomes nums[nums[1*(nums[0]+1-1)]] ; 3
22 | int num23 becomes 1*(3+4+(6*4+3)) ; 34 (22h)
23 | int num4 becomes 3+3*4*5+3*3 ; 72 (48h)
24 | int num5 becomes 3+(g(3)*3) ; 3+9, 12 (0Ch)
25 | int num6 becomes nums[nums[5*(nums[0]+1/2)]-1] ; 1
26 | int num7 becomes 3*(nums[2]+1/2) ; 3*(3+1/2), 3*(3+0), 9 (Note: 3*(nums[2]+1/2) works)
27 | int num8 becomes 3*((nums[1]*4)+3) ; 3*(2*4+3), 3*11, 33 (21h)
28 | int num9 becomes 16%5 ; 1
29 | int num10 becomes nums[(6/2)-1] ; 3
30 | int num11 becomes 1+2+3+4+5-6 ;15-6, 9
31 | int num12 becomes (1 + 3 * (4+3) /2) ; 11 (0Bh)
32 | int num13 becomes (123 + 123) ;F6h
33 |
34 | retn(g(123 + 123))
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Initialize array from many values.txt:
--------------------------------------------------------------------------------
1 | dllref(User32,str,str,int) cdecl:wsprintfA int
2 | dllref(User32,int,str,str,int) MessageBoxA int
3 |
4 | func(int i) feedback int { retn(i) }
5 |
6 | int myVar becomes 123
7 | int# myArr becomes #,(1,2,3,4,myVar,myVar,123,feedback(22),21)
8 | str buffer becomes "Num: ###"
9 | str format becomes "Num: %d"
10 |
11 | foreach (num,myArr) {
12 |
13 | wsprintfA(buffer,format,num)
14 | MessageBoxA(0,buffer,"",0)
15 |
16 | }
17 |
18 | ; Resulting Message Box Messages:
19 | ; 1
20 | ; 2
21 | ; 3
22 | ; 4
23 | ; 123
24 | ; 123
25 | ; 123
26 | ; 22
27 | ; 21
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Integer to Byte Demo/source.txt:
--------------------------------------------------------------------------------
1 | ; Variables can be converted to lower byte size variable types at
2 | ; the risk of losing data. Data will be lost in some particular scenarios,
3 | ; i.e: a integer with a size of >255 is being converted to a byte,
4 | ; or an integer with a size of >65535 is being converted to a short.
5 |
6 | ; This is a healthy example of Integer to Byte conversion via casting:
7 |
8 | int myNum becomes 123
9 | byte otherNum becomes cast(myNum,byte)
10 |
11 | retn(otherNum)
12 |
13 | ; Expected exit code: 123. (7Bh)
14 |
15 | ; Exit code result: 123. (7Bh)
16 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Labels and Goto.txt:
--------------------------------------------------------------------------------
1 | ; Labels are markers in the file that can be made anywhere outside of blocks
2 | ; and jumped to from anywhere via the goto keyword. They are not directly
3 | ; accessible outside of the containing file and modifiers do not apply to labels.
4 |
5 | ; A reason that a label is significant given the correct siutuation,
6 | ; is because instructional code can be written outside of blocks.
7 |
8 | ; An example:
9 |
10 | TOGGLE_GUI
11 |
12 | dllref(User32,int,str,str,int) MessageBoxA int
13 |
14 | int i becomes 123
15 |
16 | ~start ; This line defines a label named "start"
17 |
18 | if(i,=,0) {
19 |
20 | ; This jumps to the not yet defined "here" label
21 | goto(here)
22 |
23 | }
24 |
25 | --i
26 |
27 | goto(start) ; Usage of the goto keyword in this manner is similar to that of a loop
28 | ; ^ this goto keyword jumps to the aforementioned start label
29 |
30 | ~here
31 | MessageBoxA(0,"Here","",0)
32 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/List Demo/source.txt:
--------------------------------------------------------------------------------
1 | import(List)
2 | import(Windows\ErrorHandler)
3 | dllref(User32,int,str,str,int) MessageBoxA int
4 | dllref(User32,str,str,int) cdecl:wsprintfA int
5 |
6 | List myList becomes new(List)
7 | myList.add(123)
8 | MessageBoxA(0,"Test","Hello",0)
9 | str buffer becomes "###"
10 | wsprintfA(buffer,"%d",myList.get(0))
11 | MessageBoxA(0,buffer,"",0)
12 |
13 | myList.add(126)
14 | buffer becomes "###"
15 | wsprintfA(buffer,"%d",myList.get(1))
16 | MessageBoxA(0,buffer,"",0)
17 |
18 | foreach (i,myList.toArray) {
19 |
20 | wsprintfA(buffer,"%d",i+100)
21 | MessageBoxA(0,buffer,"",0)
22 |
23 | }
24 |
25 | ErrorHandler eh becomes new(ErrorHandler)
26 | myList.get(2) ; Out of bounds (Only added 2 items to list, this would be 3rd in zero-based index)
27 | eh.mboxLastError
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Modifiers/MyClass.sunset:
--------------------------------------------------------------------------------
1 | ; Public, Private, Local, Pullable, Static and Constant are modifiers for variables, functions or both.
2 | ; 'Private' is applied by default to any instances which don't declare an accessor modifier (Public, Private, Local, Pullable)
3 |
4 | ; Variable and Function modifiers:
5 |
6 | ; public - If an instance is declared with the 'public' modifier, it can be accessed from any file anywhere.
7 | ; private - If an instance is declared with the 'private' modifier, it can be only accessed from its containing file.
8 | ; local - If an instance is declared with the 'local' modifier, it can be only accessed from within its containing folder.
9 | ; static - If an instance is declared with the 'static' modifier, it can be accessed without a class instance. Static functions cannot access non-static instances.
10 |
11 | ; Variable exclusive modifiers:
12 |
13 | ; pullable - If an instance is declared with the 'pullable' modifier, it can be accessed from any file anywhere, except it can only be read (pulled), but not modified.
14 | ; constant - If an instance is declared with the 'constant' modifier, it must be given a value immediately and can not change.
15 |
16 | TOGGLE_GUI
17 |
18 | static private dllref(User32,str,str,int) cdecl:wsprintfA int
19 | static private dllref(User32,int,str,str,int) MessageBoxA int
20 |
21 | public int num becomes 123
22 |
23 | local int num0 becomes 0
24 |
25 | public static int num1 becomes 1233
26 |
27 | int num2 becomes 13253
28 |
29 | constant private int num3 becomes 55555
30 | constant public int num4 becomes 44444
31 | constant static public int CONSTANT_STATIC_PUBLIC_NUMBER becomes 66666
32 |
33 | private int num5 becomes 77777
34 |
35 | int num6 becomes 88888 ; private by default
36 |
37 | pullable int num7 becomes 99999
38 |
39 | str buffer becomes "#######"
40 | str format becomes "%d"
41 | str empty becomes ""
42 |
43 | static public int static_num becomes 5652
44 |
45 | local func(int i) mbox {
46 |
47 | wsprintfA(buffer,format,i)
48 | MessageBoxA(null,buffer,empty,null)
49 |
50 | }
51 |
52 | static public func show_num_static {
53 |
54 | str z becomes "#####"
55 | wsprintfA(z,"%d",static_num)
56 | MessageBoxA(null,z,"Static number",null)
57 | ; TODO:: SHOULD FAIL ON:
58 | ; num7 becomes 11111
59 |
60 | }
61 |
62 | public func show_num {
63 |
64 | wsprintfA(buffer,format,static_num)
65 | MessageBoxA(null,buffer,"Static number",null)
66 |
67 | }
68 |
69 | ;mbox(num)
70 | ;mbox(num0)
71 | ;mbox(num1)
72 | ;mbox(num2)
73 | ;mbox(num3)
74 | ;mbox(num4)
75 | ;mbox(CONSTANT_STATIC_PUBLIC_NUMBER)
76 | ;mbox(num5)
77 | ;mbox(num6)
78 | ;mbox(num7)
79 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Modifiers/Test/TestClass.sunset:
--------------------------------------------------------------------------------
1 | local func test { }
2 |
3 | static func test0 {
4 |
5 | nofunct(32)
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Modifiers/source.txt:
--------------------------------------------------------------------------------
1 | import(Documentation/Modifiers/MyClass)
2 | import(Documentation/Modifiers/Test/TestClass)
3 |
4 | MyClass class becomes new(MyClass)
5 | TestClass t_class becomes new(TestClass)
6 |
7 | class.mbox(2134)
8 | ; This line would fail:
9 | ; t_class.test
10 | ; t_class.test is a local function in a seperate folder from the containing folder of this file
11 |
12 | class.num becomes 33
13 | class.mbox(class.num)
14 |
15 | constant int b becomes 3000
16 | ; Constants must be set immediately
17 |
18 | ; Static class access:
19 | class.show_num
20 | MyClass.show_num_static
21 |
22 | MyClass.static_num becomes 333
23 | MyClass.show_num_static
24 | class.show_num
25 | MyClass class0 becomes new(MyClass)
26 | class0.show_num
27 |
28 | retn(b)
29 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Multi Foreach.txt:
--------------------------------------------------------------------------------
1 | ; Using multi foreach (mforeach) many arrays can be looped through in a single block
2 | ; The format for the parameters is item,array,item0,array0,item1,array1 ....
3 | ; Only arrays are valid (Aug 24 06:53 2021)
4 | ; The parameters must be divsible by 2 and they are in pairs: 'item,array' item corresponds to the next listed parameter
5 | ; The collections used in the multi foreach loop can have different lengths, however the loop will break after the collection with the smallest length reaches its last item
6 |
7 | ; An example:
8 |
9 | TOGGLE_GUI
10 |
11 | dllref(User32,str,str,int,int,int) cdecl:wsprintfA int
12 | dllref(User32,int,str,str,int) MessageBoxA int
13 |
14 | int# arr becomes #,(1,2,3,4,5)
15 | int# arr0 becomes #,(10,9,8,7,6,5,4,3,2,1)
16 | int# arr1 becomes #,(1,2,4,8,16,32,64,128,256,512,1024,2048)
17 |
18 | str buffer becomes "No. #: ##: ###"
19 | str format becomes "No. %d: %d: %d"
20 | str empty becomes ""
21 |
22 | mforeach(n,arr,n0,arr0,n1,arr1) {
23 |
24 | ; This block will loop 5 times - lengthof(arr)
25 | ; Local variables defined at this point:
26 | ; int n
27 | ; int n0
28 | ; int n1
29 |
30 | wsprintfA(buffer,format,n,n0,n1)
31 | MessageBoxA(0,buffer,empty,0)
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Passing Acknowledgements Demo/MyClass.sunset:
--------------------------------------------------------------------------------
1 | acknowledge TEST_ACK as int
2 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Passing Acknowledgements Demo/source.txt:
--------------------------------------------------------------------------------
1 | import(Documentation/Passing Acknowledgements Demo/MyClass)
2 | TEST_ACK num becomes 123
3 | retn(num)
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Passing Var Types into Class Demo/MyClass.sunset:
--------------------------------------------------------------------------------
1 | EXPECTED_TYPES(T,T0)
2 | import(Documentation\Passing Var Types into Class Demo\OtherClass)
3 |
4 | T oc becomes new(OtherClass) ; T == OtherClass in this example (See ./source.txt)
5 | T0# nums becomes #3 ; T0 == int in this example (See ./source.txt)
6 |
7 | nums[0] becomes 1
8 | nums[1] becomes 2
9 | nums[2] becomes 3
10 |
11 | func test T {
12 |
13 | OtherClass oc0 becomes new(OtherClass)
14 | retn(oc0)
15 |
16 | }
17 |
18 | func test0 OtherClass {
19 |
20 | T oc0 becomes new(OtherClass)
21 | retn(oc0)
22 |
23 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Passing Var Types into Class Demo/OtherClass.sunset:
--------------------------------------------------------------------------------
1 | dllref(User32,int,str,str,int) MessageBoxA int
2 | MessageBoxA(0,"Hello (OtherClass reached)","",0)
3 |
4 | func test { MessageBoxA(0,"Test","From OtherClass",0) }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Passing Var Types into Class Demo/source.txt:
--------------------------------------------------------------------------------
1 | import(Documentation\Passing Var Types into Class Demo\OtherClass)
2 | import(Documentation\Passing Var Types into Class Demo\MyClass)
3 |
4 | dllref(User32,int,str,str,int) MessageBoxA int
5 | dllref(User32,str,str,int) cdecl:wsprintfA int
6 |
7 | MyClass mc becomes new(MyClass)
8 | str buffer becomes "#"
9 | wsprintfA(buffer,"%d",mc.nums[1])
10 | MessageBoxA(0,buffer,"",0)
11 | OtherClass oc becomes mc.test
12 | OtherClass oc0 becomes mc.oc
13 | oc0.test
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Simple Forms Game/source.txt:
--------------------------------------------------------------------------------
1 | import(Windows/Form)
2 | import(Windows/TimerEventArgs)
3 | import(Windows/FormEventArgs)
4 | import(Windows/RECT)
5 | import(Windows/KeyEventArgs)
6 | Form form becomes new(Form,"My Form",100,100,400,360)
7 | RECT player becomes new(RECT)
8 | player.top becomes 100
9 | player.bottom becomes 200
10 | player.left becomes 0
11 | player.right becomes 100
12 | int gravity becomes 2
13 | int groundLevel becomes 334 ; should be divisible by gravity
14 | int speed becomes 8
15 | int jumpTicks becomes 0
16 | int jumpPower becomes gravity*2
17 |
18 | func(TimerEventArgs args) formTick {
19 |
20 | if (jumpTicks,=/=,0) {
21 |
22 | player.top becomes player.top-jumpPower
23 | player.bottom becomes player.bottom-jumpPower
24 | --jumpTicks
25 | form.rePaint
26 |
27 | }
28 | else {
29 | if (player.bottom,=/=,groundLevel) {
30 | player.top becomes player.top+gravity
31 | player.bottom becomes player.bottom+gravity
32 | form.rePaint
33 | }
34 | }
35 |
36 |
37 | }
38 |
39 | func(KeyEventArgs args) keyDown {
40 |
41 | switch(args.keyCode) {
42 |
43 | case(32): ; SPACE BAR
44 | if (player.bottom,=/=,groundLevel) { break }
45 | jumpTicks becomes 20
46 | break
47 | case(37): ; LEFT ARROW KEY
48 | player.left becomes player.left-speed
49 | player.right becomes player.right-speed
50 | form.rePaint
51 | break
52 | case(39): ; RIGHT ARROW KEY
53 | player.left becomes player.left+speed
54 | player.right becomes player.right+speed
55 | form.rePaint
56 | break
57 |
58 | }
59 |
60 | }
61 |
62 | func(FormEventArgs args) init {
63 |
64 | form.onTimerTick.addFunction($formTick)
65 | form.createTimer(13)
66 | form.rectangles.add(player)
67 | form.onKeyDown.addFunction($keyDown)
68 |
69 | }
70 |
71 | form.onFormCreation.addFunction($init)
72 | form.show
73 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/MSG.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(POINT)
3 | int hwnd
4 | int message
5 | int wParam
6 | int lParam
7 | int time
8 | POINT point
9 | int lPrivate
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/PAINTSTRUCT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(RECT)
3 | int hdc
4 | bool fErase
5 | RECT rcPaint
6 | bool fRestore
7 | bool fIncUpdate
8 | int res int res0 int res1 int res2 int res3 int res4 int res5 int res6
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/POINT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | int x
3 | int y
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/RECT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | int left
3 | int top
4 | int right
5 | int bottom
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/WNDCLASSA.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | int style
3 | int lpfnWndProc
4 | int cbClsExtra
5 | int cbWndExtra
6 | int hInstance
7 | int hIcon
8 | int hCursor
9 | int hbrBackground
10 | str lpszMenuName
11 | str lpszClassName
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Struct Demo/source.txt:
--------------------------------------------------------------------------------
1 | TOGGLE_GUI
2 |
3 | import(WNDCLASSA)
4 | import(MSG)
5 |
6 | dllref(User32,WNDCLASSA) RegisterClassA int
7 | dllref(Kernel32,str) GetModuleHandleA int
8 | dllref(User32,int,str,str,int,int,int,int,int,int,int,int,int) CreateWindowExA int
9 | dllref(User32,MSG,int,int,int) GetMessageA bool
10 | dllref(User32,MSG) TranslateMessage void
11 | dllref(User32,MSG) DispatchMessageA void
12 | dllref(User32,int,str,str,int) MessageBoxA int
13 | dllref(User32,int,int,int,int) DefWindowProcA int
14 | dllref(User32,int) PostQuitMessage void
15 |
16 | int WM_DESTROY becomes 2
17 | int modh becomes GetModuleHandleA(null)
18 | int cHwnd
19 | int COLOR_WINDOW becomes 5
20 |
21 | func(str message) mbox { MessageBoxA(null,message,message,null) }
22 | func(int hwnd,int uMsg,int wParam,int lParam) wndProc int {
23 |
24 | if (uMsg,=,WM_DESTROY) {
25 |
26 | mbox("Goodbye")
27 | PostQuitMessage(null)
28 | retn(0)
29 |
30 | }
31 |
32 | retn(DefWindowProcA(hwnd,uMsg,wParam,lParam))
33 |
34 | }
35 |
36 | WNDCLASSA wndClassA becomes new(WNDCLASSA)
37 | wndClassA.hInstance becomes modh
38 | wndClassA.lpfnWndProc becomes $wndProc
39 | wndClassA.lpszClassName becomes "SunsetClass"
40 | wndClassA.hbrBackground becomes COLOR_WINDOW+1
41 | RegisterClassA(wndClassA)
42 | cHwnd becomes CreateWindowExA(null,"SunsetClass","Sunset GUI",273154048,128,128,256,192,null,null,modh,null)
43 |
44 | MSG msg becomes new(MSG)
45 | while(GetMessageA(msg,null,null,null)) {
46 |
47 | TranslateMessage(msg)
48 | DispatchMessageA(msg)
49 |
50 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/Switch, Case and Default.txt:
--------------------------------------------------------------------------------
1 | int i becomes 4
2 | int j becomes 1
3 | switch (i) {
4 |
5 | ; The following line would throw a ParsingError because only
6 | ; case and default blocks can be run from within a switch block:
7 | ; int num becomes 123
8 |
9 | case(0):
10 | break ; On break, the end of the switch block is jumped to. If
11 | ; no break and/or case is false, then the next case is tested.
12 |
13 | case(j): ; Non-constant values can be used as parameters for case
14 | i becomes 3
15 | break
16 |
17 | ; With multiple parameters, the block will be run if
18 | ; any of the cases are calculated as true
19 | case(3,4): ; This case will fall through to the default case because
20 | ; it has no 'break' word, so they will both be run.
21 | i becomes 6
22 | default: ; Default block is executed in the order it is written
23 | ; in from within the switch block. Multiple default
24 | ; blocks are permitted.
25 | ++i
26 | break ; <-- Remember to ultimately close all cases with a break word
27 |
28 |
29 | }
30 | retn(i)
31 | ; -----------------------
32 | ; - FOR VARIABLE 'i' -
33 | ; - OUTPUT: EXIT CODE -
34 | ; -----------------------
35 | ; -INPUT-EXPECTED-OUTPUT-
36 | ; -----------------------
37 | ; - 0 - 0 - 0 -
38 | ; - 1 - 3 - 3 -
39 | ; - 2 - 3 - 3 -
40 | ; - 3 - 7 - 7 -
41 | ; - 4 - 7 - 7 -
42 | ; -----------------------
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/While Loops.txt:
--------------------------------------------------------------------------------
1 | int i becomes 0
2 |
3 | ; Loop a boolean, in this case "true", resulting in an infinite loop
4 | while (true) {
5 |
6 | if(i,=,10) {
7 |
8 | break
9 |
10 | }
11 | else {
12 |
13 | ++i
14 |
15 | }
16 |
17 | }
18 |
19 | ; Resetting the variable i to 0
20 | i becomes 0
21 |
22 | ; This is the equivalent of the above loop without using break
23 | ; (Except shortened and therefore optimized)
24 | while (i,=/=,10) {
25 |
26 | ++i
27 |
28 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Documentation(OUTDATED MOSTLY GONNA REDO IT WHEN DONE)/lengthof, sizeof and Tsizeof.txt:
--------------------------------------------------------------------------------
1 | dllref(User32,int,str,str,int) MessageBoxA int
2 | dllref(User32,str,str,int) cdecl:wsprintfA int
3 |
4 | int i
5 | shr s
6 | byte b
7 | str buffer becomes "######"
8 | str format becomes "%d"
9 |
10 | int# arr becomes #3
11 | shr# arr0 becomes #7
12 | byte# arr1 becomes #65536
13 |
14 | func(int num) mboxNum {
15 | wsprintfA(buffer,format,num)
16 | MessageBoxA(0,buffer,"",0)
17 | }
18 |
19 | ; --- lengthof --- ;
20 | ; lengthof: Get the length of an array
21 | ; (For length of Strings, use StringTool.lengthOf)
22 | ; (Alternative way to get length of Strings is to iterate all bytes of string in a foreach. The # of bytes is the length of the string)
23 | mboxNum(lengthof(arr)) ;3
24 | mboxNum(lengthof(arr0)) ;7
25 | mboxNum(lengthof(arr1)) ;65536
26 |
27 | ; --- sizeof --- ;
28 | ; sizeof: Get the byte size of a variable
29 | ; sizeof: When used on an array, gets the byte size of the array type
30 | ; i.e: sizeof on int arrays will return the byte size of ints (4), sizeof on short arrays will return the byte size of shorts (2)
31 | mboxNum(sizeof(i)) ;4
32 | mboxNum(sizeof(s)) ;2
33 | mboxNum(sizeof(b)) ;1
34 | mboxNum(sizeof(buffer)) ;4
35 | mboxNum(sizeof(format)) ;4
36 |
37 | mboxNum(sizeof(arr)) ;4
38 | mboxNum(sizeof(arr0)) ;2
39 | mboxNum(sizeof(arr1)) ;1
40 |
41 | ; --- Tsizeof --- ;
42 | ; Tsizeof: Get the byte size of a type of variable
43 | ; Tsizeof: Works for EXPECTED_TYPES var types
44 | mboxNum(Tsizeof(int)) ;4
45 | mboxNum(Tsizeof(str)) ;4
46 | mboxNum(Tsizeof(shr)) ;2
47 | mboxNum(Tsizeof(byte)) ;1
48 | mboxNum(Tsizeof(bool)) ;1
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Event.sunset:
--------------------------------------------------------------------------------
1 | EXPECTED_TYPES(EvtArgs)
2 | import(List)
3 |
4 | private List pointers becomes new(List)
5 | pullable int references
6 |
7 | public func(FUNCPTR ptr) addFunction { pointers.add(ptr) ++references }
8 |
9 | public func(EvtArgs args) raise {
10 |
11 | foreach(ptr,pointers.toArray) {
12 |
13 | ;if (ptr,=,null) { continue }
14 | callptr(ptr,args)
15 |
16 | }
17 |
18 | }
19 |
20 | public func (FUNCPTR ptr) removeFunction bool {
21 |
22 | int index becomes pointers.indexOf(ptr)
23 | if (index,=,-1) { retn(false) }
24 | pointers.remove(index)
25 | references becomes references-1
26 | retn(true)
27 |
28 | }
29 |
30 | public func clearFunctions { pointers.clear references becomes 0 }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/ImageReference.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public str fileName
3 | public int x
4 | public int y
5 | public int width
6 | public int height
7 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Important/DemoProject.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/MessageBox)
2 |
3 | MessageBox.mbox("Hello World","")
--------------------------------------------------------------------------------
/Sunset/bin/Debug/List.sunset:
--------------------------------------------------------------------------------
1 | EXPECTED_TYPES(T)
2 | dllref(Kernel32,int,int,T#) HeapFree bool
3 | dllref(Kernel32,int) SetLastError void
4 |
5 | T# innerList becomes #0
6 | pullable int length becomes 0
7 |
8 | public func(T item) add {
9 |
10 | T# newArr becomes #length+1
11 | int i becomes 0
12 | while (i,=/=,length) {
13 | newArr[i] becomes innerList[i]
14 | ++i
15 | }
16 | newArr[length] becomes item
17 | ; Note, GetProcessHeap stores the process heap after it is retrieved for the first time (so re calling it isn't detrimental)
18 | HeapFree(getProcessHeap,null,innerList)
19 | innerList becomes newArr
20 |
21 | ++length
22 |
23 | }
24 |
25 | public func(int index) get T {
26 |
27 | ; ERROR_NO_MATCH
28 | if (index,>=,length) { SetLastError(1169) }
29 | retn(innerList[index])
30 |
31 | }
32 |
33 | ; Note: this will be referenced to the List (any updates on the array will update the list)
34 | public func toArray T# { retn(innerList) }
35 |
36 | public func(int index) remove {
37 |
38 | T# newArr becomes #length-1
39 | int i becomes 0
40 | int i0 becomes 0
41 | while (i,=/=,length) {
42 | if (i,=/=,index) {
43 | newArr[i0] becomes innerList[i]
44 | ++i0
45 | }
46 | ++i
47 | }
48 | HeapFree(getProcessHeap,null,innerList)
49 | innerList becomes newArr
50 |
51 | length becomes length-1
52 |
53 | }
54 |
55 | public func(T item) indexOf int {
56 |
57 | int index becomes 0
58 | foreach(item0,innerList) {
59 | if (item,=,item0) { retn(index) }
60 | ++index
61 | }
62 | retn(-1)
63 |
64 | }
65 |
66 | ; doesn't work for some reason?!
67 | ;public func(T item,int index) insert {
68 | ;
69 | ; ++length
70 | ; T# newArr becomes #length
71 | ; int i becomes 0
72 | ; int i0 becomes 0
73 | ; while (i,=/=,length) {
74 | ; if (i,=,index) {
75 | ; newArr[i] becomes item
76 | ; }
77 | ; else {
78 | ; newArr[i] becomes innerList[i0]
79 | ; ++i0
80 | ; }
81 | ; ++i
82 | ; }
83 | ; HeapFree(getProcessHeap,null,innerList)
84 | ; innerList becomes newArr
85 | ;
86 | ;}
87 |
88 | public func(T item,int index) set {
89 |
90 | T# newArr becomes #length
91 | int i becomes 0
92 | int i0 becomes 0
93 | while (i,=/=,length) {
94 | if (i,=/=,index) {
95 | newArr[i] becomes innerList[i]
96 | }
97 | else {
98 | newArr[i] becomes item
99 | }
100 | ++i
101 | }
102 | HeapFree(getProcessHeap,null,innerList)
103 | innerList becomes newArr
104 |
105 | }
106 |
107 | public func clear {
108 |
109 | HeapFree(getProcessHeap,null,innerList)
110 | innerList becomes #0
111 | length becomes 0
112 |
113 | ;int i becomes 0
114 | ;int len becomes length
115 | ;while (i,=/=,len) {
116 | ; remove(0)
117 | ; ++i
118 | ;}
119 |
120 | }
121 |
122 | public func(T# range) addRange {
123 |
124 | foreach (item,range) {
125 | add(item)
126 | }
127 |
128 | }
129 |
130 | public func(T item) contains bool {
131 | foreach (item0,innerList) {
132 | if (item0,=,item) { retn(true) }
133 | }
134 | retn(false)
135 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Math.sunset:
--------------------------------------------------------------------------------
1 | public static func(int num) absolute int {
2 |
3 | if (num,<,0) {
4 | retn(num*(-1))
5 | }
6 | retn(num)
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Numbers.sunset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Debug/Numbers.sunset
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Random.sunset:
--------------------------------------------------------------------------------
1 | ; Only temporary
2 | ; Should be redone
3 | ; And definitely shouldn't be used with large numbers
4 |
5 | dllref(Kernel32) GetTickCount int
6 |
7 | private static int xch
8 |
9 | ;Min=zero
10 | public static func(int max) gen int {
11 |
12 | retn(GetTickCount%(max+1))
13 |
14 | }
15 |
16 | ; Very pseudo-random here
17 | public static func(int max) genXch int {
18 |
19 | xch becomes xch+1
20 | if (xch%7,=,0) {
21 | if (gen(1),=,1) {
22 | xch becomes 0
23 | }
24 | }
25 | if (xch%3,=,0) {
26 | if (gen(2),=,1) {
27 | xch becomes 13
28 | }
29 | }
30 | retn((GetTickCount+xch)%(max+1))
31 |
32 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/String.sunset:
--------------------------------------------------------------------------------
1 | acknowledge char as byte
2 | acknowledge WCHAR as int
3 | ; ASCII:
4 | static constant public char A becomes 65
5 | static constant public char a becomes 97
6 | static constant public char Z becomes 90
7 | static constant public char z becomes 122
8 | ; -----
9 |
10 | public static func(str string) lengthOf int {
11 |
12 | int i becomes 0
13 | foreach (b,string) { ++i }
14 | retn(i)
15 |
16 | }
17 | ;stringFromBytes -> Parameter bytes should contain a null terminator byte
18 | public static func(byte# bytes) fromBytes str { retn(bytes+8) }
19 | public static func(str string) toBytes byte# {
20 |
21 | byte# arr becomes #lengthOf(string)+1
22 | int i becomes 0
23 | foreach (b,string) {
24 |
25 | arr[i] becomes b
26 | ++i
27 |
28 | }
29 | retn(arr)
30 |
31 | }
32 | public static func(str prefix,str suffix) concat str {
33 |
34 | byte# arr becomes #lengthOf(prefix)+lengthOf(suffix)+1
35 | int i becomes 0
36 | foreach (b,prefix) {
37 |
38 | arr[i] becomes b
39 | ++i
40 |
41 | }
42 | foreach (b,suffix) {
43 |
44 | arr[i] becomes b
45 | ++i
46 |
47 | }
48 | retn(fromBytes(arr))
49 |
50 | }
51 | public static func(str string,int startIndex,int endIndex) substring str {
52 |
53 | if (startIndex,>,endIndex) { retn("") }
54 |
55 | byte# arr becomes #(endIndex-startIndex)+1
56 | byte# arr0 becomes toBytes(string)
57 | int i becomes 0
58 | while (startIndex,=/=,endIndex) {
59 |
60 | arr[i] becomes arr0[startIndex]
61 |
62 | ++i
63 | ++startIndex
64 |
65 | }
66 | retn(fromBytes(arr))
67 |
68 | }
69 | public static func(byte b) byteToCorrespondingASCII str {
70 |
71 | byte# arr becomes #2
72 | arr[0] becomes b
73 | retn(fromBytes(arr))
74 |
75 | }
76 | public static func(str string) quote str {
77 |
78 | str quotation becomes byteToCorrespondingASCII(34)
79 | string becomes concat(quotation,string)
80 | string becomes concat(string,quotation)
81 | retn(string)
82 |
83 | }
84 |
85 | ; FUNCPTR func -> 1 Paramter: Byte (the current char), Return Value: Bool (true if meets criteria and vice versa)
86 | public static func (str string,FUNCPTR func) where str {
87 |
88 | byte# arr becomes #lengthOf(string)+1
89 | int i becomes 0
90 | foreach (b,string) {
91 |
92 | if (callptr(func,b),=/=,0) {
93 |
94 | arr[i] becomes b
95 | ++i
96 |
97 | }
98 |
99 | }
100 | retn(fromBytes(arr))
101 |
102 | }
103 | public static func(str string) toUpper str {
104 |
105 | byte# arr becomes #lengthOf(string)+1
106 | int i becomes 0
107 | foreach (b,string) {
108 |
109 | if (b,>=,a) {
110 | if (b,<=,z) {
111 | b becomes cast(b-32,byte)
112 |
113 | }
114 | }
115 | arr[i] becomes b
116 | ++i
117 |
118 | }
119 | retn(fromBytes(arr))
120 |
121 | }
122 | public static func(str string) toLower str {
123 |
124 | byte# arr becomes #lengthOf(string)+1
125 | int i becomes 0
126 | foreach (b,string) {
127 |
128 | if (b,>=,A) {
129 | if (b,<=,Z) {
130 | b becomes cast(b+32,byte)
131 |
132 | }
133 | }
134 | arr[i] becomes b
135 | ++i
136 |
137 | }
138 | retn(fromBytes(arr))
139 |
140 | }
141 | public static func(str string) toWchars WCHAR# {
142 |
143 | int# arr becomes #lengthOf(string)+1
144 | int ctr becomes 0
145 | foreach (b,string) {
146 |
147 | arr[ctr] becomes cast(b,int)
148 | ++ctr
149 |
150 | }
151 | retn(cast(arr,WCHAR#))
152 |
153 | }
154 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Sunset.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Debug/Sunset.exe
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Sunset.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Sunset.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Debug/Sunset.pdb
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Sunset_Syntax.esy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Debug/Sunset_Syntax.esy
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Todo list.txt:
--------------------------------------------------------------------------------
1 | Current:
2 |
3 | - dowhile {...} (like do{...}while(...))
4 | - free array heaps on block end (when the block they were defined in closes) or if they weren't defined in a block, on class end
5 | - blogic (pb)
6 | - for loops - Set the parser to parse the first parameter normally but set the block to the for block
7 | - or keyword (See bottom of doc)
8 | - fix the issue where if a class gets too big (byte size) there is a crash
9 |
10 | ~~~
11 | TODO/FIXME :: in solution
12 | ~~~
13 | REDO DOCS, TEST (INCLUDE) ALL FEATURES OF LANGUAGE AND ALL UPDATED LIBS. (FIRST OPTIMIZE LIBS SO THEY WON'T CHANGE MUCH AND A LEGACY CHANGE (DEPRECATION) WOULDN'T BE THE END OF THE WORLD)
14 | ~~~
15 | LET ARRAYS BE PASSED EXTERNALLY EASILY (i.e without +8, maybe make automatic, or for native support maybe just add Arrays.toNative(arr). Be sure to count for array styles because static arrays shouldn't have +8.)
16 | ~~~
17 | LINUX LIBS & LINUX SUPPORT
18 | ~~~
19 | STANDALONE LIBS, ALLOW OS TO BE MADE ENTIRELY USING SUNSET, (using arraystyle.static arrays to write bytes and such). Also make SetOrigin keyword that is like the org instruction in fasm
20 | ~~~
21 | - Only one class reference block should be made per compilation, so if it already exists from a previous Parser, don't make a new one, instead reference the initial one
22 | - Let enums be of different types other than native var int (i.e add syntax ENUM(shr) and there can be shr enums like in C# public enum yatta : UInt16 { ... })
23 | - magic #'s, neural network, creative ways all to give unique performance !
24 |
25 |
26 | ; or keyword: (abs is a synonym for absolute without making a new func in memory)
27 | public static func(int num) absolute or abs int {
28 |
29 | if (num,<,0) {
30 | retn(num*(-1))
31 | }
32 | retn(num)
33 |
34 | }
35 |
36 | ; It can also be done like this:
37 | func test or test0 or test1 {
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Tuple.sunset:
--------------------------------------------------------------------------------
1 | EXPECTED_TYPES(T,T0)
2 | public T item
3 | public T0 item0
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/CollisionEventArgs.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Drawing/RECT)
2 | STRUCT
3 | public int x
4 | public int y
5 | public RECT hitbox
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/Button.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/PaintMsg)
2 | import(Windows/Drawing/POINT)
3 | import(Windows/Components/Component)
4 | import(Windows/Drawing/SIZE)
5 | import(String)
6 | import(Windows/MouseEventArgs)
7 | import(Event)
8 | acknowledge HBRUSH as PTR
9 | acknowledge HDC as PTR
10 | acknowledge HWND as PTR
11 | dllref(Gdi32,HDC,int,int,POINT) MoveToEx bool
12 | dllref(Gdi32,HDC,int,int) LineTo bool
13 | dllref(Gdi32,HDC,str,int,SIZE) GetTextExtentPoint32A bool
14 | dllref(User32,HWND) GetDC HDC
15 | dllref(Gdi32,HDC,int,int,str,int) TextOutA bool
16 |
17 | INHERIT(Component)
18 | public int x
19 | public int y
20 | public int width
21 | public int height
22 | public str text
23 | public Event onBtnClick becomes new(Event)
24 |
25 | public func(PaintMsg pm) onPaint {
26 |
27 | MoveToEx(pm.hdc,x,y,null)
28 | LineTo(pm.hdc,x+width,y)
29 | LineTo(pm.hdc,x+width,y+height)
30 | LineTo(pm.hdc,x,y+height)
31 | LineTo(pm.hdc,x,y)
32 |
33 | SIZE textSize becomes new(SIZE)
34 | int strlen becomes String.lengthOf(text)
35 | if (GetTextExtentPoint32A(pm.hdc,text,strlen,textSize)) {
36 | while (textSize.cx,>=,width) {
37 | strlen becomes strlen-1
38 | GetTextExtentPoint32A(pm.hdc,text,strlen,textSize)
39 | }
40 | TextOutA(pm.hdc,x+1,y+1,text,strlen)
41 | }
42 |
43 | }
44 |
45 | public func(MouseEventArgs e) onClick { onBtnClick.raise(e) }
46 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/Component.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/PaintMsg)
2 | import(Windows/MouseEventArgs)
3 | public int x
4 | public int y
5 | public int width
6 | public int height
7 | public func(PaintMsg pm) onPaint { }
8 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/Ellipse.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HDC as PTR
2 | import(Windows/Components/Component)
3 | import(Windows/MouseEventArgs)
4 | import(Windows/PaintMsg)
5 | dllref(Gdi32,HDC,int,int,int,int) Ellipse bool
6 | INHERIT(Component)
7 | public int x
8 | public int y
9 | public int width
10 | public int height
11 | public func(PaintMsg pm) onPaint {
12 |
13 | Ellipse(pm.hdc,x,y,x+width,y+height)
14 |
15 | }
16 |
17 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/FormImage.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HDC as PTR
2 | acknowledge HBITMAP as PTR
3 | acknowledge HGDIOBJ as PTR
4 | import(Windows/Components/Component)
5 | import(Windows/MouseEventArgs)
6 | import(Windows/PaintMsg)
7 | import(Windows/Drawing/BITMAP)
8 | dllref(Gdi32,HDC,int,int,int,int) Ellipse bool
9 | dllref(Gdi32,HDC) CreateCompatibleDC HDC
10 | dllref(Gdi32,HDC,HGDIOBJ) SelectObject HGDIOBJ
11 | dllref(Gdi32,HDC,int,int,int,int,HDC,int,int,int) BitBlt bool
12 | dllref(Gdi32,HDC) DeleteDC bool
13 | dllref(Gdi32,HBITMAP,int,BITMAP) GetObjectA int
14 | dllref(Kernel32,int) ExitProcess void
15 | INHERIT(Component)
16 | public int x
17 | public int y
18 | public int width
19 | public int height
20 | public HBITMAP bitmap
21 | public func(PaintMsg pm) onPaint {
22 |
23 | HDC hMemDC becomes CreateCompatibleDC(pm.hdc)
24 | HGDIOBJ oldBitmap becomes SelectObject(hMemDC,cast(bitmap,HGDIOBJ))
25 | BITMAP bmp becomes new(BITMAP)
26 | GetObjectA(bitmap,Bsizeof(BITMAP),bmp)
27 | BitBlt(pm.hdc,x,y,width,height,hMemDC,0,0,0CC0020h)
28 | SelectObject(hMemDC,oldBitmap)
29 | DeleteDC(hMemDC)
30 |
31 | }
32 |
33 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/ListBox.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/PaintMsg)
2 | import(List)
3 | import(Windows/Drawing/POINT)
4 | import(Windows/Components/Component)
5 | import(Windows/Drawing/SIZE)
6 | import(String)
7 | import(Windows/Components/ListBoxEntry)
8 | import(List)
9 | import(Windows/MouseEventArgs)
10 | import(Windows/MessageBox)
11 | acknowledge HBRUSH as PTR
12 | acknowledge HDC as PTR
13 | acknowledge HWND as PTR
14 | dllref(Gdi32,HDC,int,int,POINT) MoveToEx bool
15 | dllref(Gdi32,HDC,int,int) LineTo bool
16 | dllref(Gdi32,HDC,str,int,SIZE) GetTextExtentPoint32A bool
17 | dllref(User32,HWND) GetDC HDC
18 | dllref(Gdi32,HDC,int,int,str,int) TextOutA bool
19 |
20 | INHERIT(Component)
21 | public int x
22 | public int y
23 | public int width
24 | public int height
25 | public List entries becomes new(List)
26 | public func(PaintMsg pm) onPaint {
27 |
28 | MoveToEx(pm.hdc,x,y-1,null)
29 | LineTo(pm.hdc,x+width,y-1)
30 | MoveToEx(pm.hdc,x-1,y-1,null)
31 | LineTo(pm.hdc,x-1,y+height+1)
32 | MoveToEx(pm.hdc,x,y+height,null)
33 | LineTo(pm.hdc,x+width,y+height)
34 | MoveToEx(pm.hdc,x+width,y-1,null)
35 | LineTo(pm.hdc,x+width,y+height+1)
36 |
37 | SIZE s becomes new(SIZE)
38 | int yOffset becomes 1
39 | int strlen
40 | HDC wdc becomes GetDC(pm.windowHandle)
41 | foreach (entry,entries.toArray) {
42 | strlen becomes String.lengthOf(entry.text)
43 | GetTextExtentPoint32A(wdc,entry.text,strlen,s)
44 | while (s.cx,>=,width) {
45 | strlen becomes strlen-1
46 | GetTextExtentPoint32A(wdc,entry.text,strlen,s)
47 | }
48 | if (yOffset+s.cy,>=,height) { break }
49 | TextOutA(pm.hdc,x+1,y+yOffset,entry.text,strlen)
50 | MoveToEx(pm.hdc,x,y+yOffset+s.cy+2,null)
51 | LineTo(pm.hdc,x+width,y+yOffset+s.cy+2)
52 | entry.top becomes y+yOffset
53 | yOffset becomes yOffset+s.cy+3
54 | entry.bottom becomes y+yOffset-1
55 | }
56 | }
57 |
58 | public func(MouseEventArgs e) onClick {
59 | int i becomes 0
60 | foreach (entry,entries.toArray) {
61 | if (e.y,>=,entry.top) {
62 | if (e.y,<=,entry.bottom) {
63 | ListBoxEntry lbe becomes entries.get(i)
64 | lbe.onClick.raise(e)
65 | }
66 | }
67 | ++i
68 | }
69 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/ListBoxEntry.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/MouseEventArgs)
2 | import(Event)
3 | public str text
4 | public Event onClick becomes new(Event)
5 | local int top
6 | local int bottom
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/ProgressBar.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Components/Component)
2 | import(Windows/PaintMsg)
3 | import(Windows/Drawing/RECT)
4 | import(Windows/Drawing/POINT)
5 | import(Windows/MouseEventArgs)
6 | acknowledge HBRUSH as PTR
7 | acknowledge HDC as PTR
8 | dllref(User32,int) GetSysColorBrush HBRUSH
9 | dllref(User32,HDC,RECT,HBRUSH) FillRect int
10 | dllref(Gdi32,HDC,int,int,POINT) MoveToEx bool
11 | dllref(Gdi32,HDC,int,int) LineTo bool
12 | INHERIT(Component)
13 |
14 | public int x
15 | public int y
16 | public int progress
17 | public int width
18 | public int height
19 | public HBRUSH brush becomes GetSysColorBrush(8)
20 |
21 | public func(PaintMsg pm) onPaint {
22 | RECT rc becomes new(RECT)
23 | rc.left becomes x
24 | rc.top becomes y
25 | rc.right becomes rc.left+((((width*100)/100)*progress)/100)
26 | rc.bottom becomes rc.top+height
27 | FillRect(pm.hdc,rc,brush)
28 | MoveToEx(pm.hdc,x,y-1,null)
29 | LineTo(pm.hdc,x+width,y-1)
30 | MoveToEx(pm.hdc,x-1,y-1,null)
31 | LineTo(pm.hdc,x-1,y+height+1)
32 | MoveToEx(pm.hdc,x,y+height,null)
33 | LineTo(pm.hdc,x+width,y+height)
34 | MoveToEx(pm.hdc,x+width,y-1,null)
35 | LineTo(pm.hdc,x+width,y+height+1)
36 |
37 | }
38 |
39 | public func(MouseEventArgs e) onClick { }
40 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/Rectangle.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HBRUSH as PTR
2 | acknowledge HDC as PTR
3 | import(Windows/Components/Component)
4 | import(Windows/MouseEventArgs)
5 | import(Windows/PaintMsg)
6 | import(String)
7 | import(Windows/Drawing/RECT)
8 | dllref(User32,int) GetSysColorBrush HBRUSH
9 | dllref(User32,HDC,RECT,HBRUSH) FillRect int
10 | INHERIT(Component)
11 | public int x
12 | public int y
13 | public int width
14 | public int height
15 | public int brush becomes GetSysColorBrush(8)
16 | public func(PaintMsg pm) onPaint {
17 |
18 | RECT rct becomes new(RECT)
19 | rct.left becomes x
20 | rct.top becomes y
21 | rct.right becomes x+width
22 | rct.bottom becomes y+height
23 | FillRect(pm.hdc,rct,brush)
24 |
25 | }
26 |
27 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/RoundRectangle.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HBRUSH as PTR
2 | acknowledge HDC as PTR
3 | import(Windows/Components/Component)
4 | import(Windows/MouseEventArgs)
5 | import(Windows/PaintMsg)
6 | import(String)
7 | dllref(Gdi32,HDC,int,int,int,int,int,int) RoundRect bool
8 | INHERIT(Component)
9 | public int x
10 | public int y
11 | public int width
12 | public int height
13 | public int cornerEllipseWidth becomes 15
14 | public int cornerEllipseHeight becomes 15
15 | public func(PaintMsg pm) onPaint {
16 |
17 | RoundRect(pm.hdc,x,y,x+width,y+height,cornerEllipseWidth,cornerEllipseHeight)
18 |
19 | }
20 |
21 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/SimpleLabel.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Components/Component)
2 | import(Windows/MouseEventArgs)
3 | import(Windows/PaintMsg)
4 | import(String)
5 | dllref(Gdi32,HDC,int,int,str,int) TextOutA bool
6 | INHERIT(Component)
7 | public str text
8 | public int x
9 | public int y
10 | public int width
11 | public int height
12 | public func(PaintMsg pm) onPaint {
13 |
14 | TextOutA(pm.hdc,x,y,text,String.lengthOf(text))
15 |
16 | }
17 |
18 | public func(MouseEventArgs e) onClick { }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Components/TreeView.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/PaintMsg)
2 | import(Windows/Drawing/POINT)
3 | import(Windows/Components/Component)
4 | import(Windows/Drawing/SIZE)
5 | import(String)
6 | import(Windows/MouseEventArgs)
7 | import(Event)
8 | acknowledge HBRUSH as PTR
9 | acknowledge HDC as PTR
10 | acknowledge HWND as PTR
11 | dllref(Gdi32,HDC,int,int,POINT) MoveToEx bool
12 | dllref(Gdi32,HDC,int,int) LineTo bool
13 | dllref(Gdi32,HDC,str,int,SIZE) GetTextExtentPoint32A bool
14 | dllref(User32,HWND) GetDC HDC
15 | dllref(Gdi32,HDC,int,int,str,int) TextOutA bool
16 |
17 | INHERIT(Component)
18 | public int x
19 | public int y
20 | public int width
21 | public int height
22 | public str text
23 | public Event onBtnClick becomes new(Event)
24 |
25 | public func(PaintMsg pm) onPaint {
26 |
27 | ; maybe put this in a static function Component#drawOutline
28 |
29 | MoveToEx(pm.hdc,x,y,null)
30 | LineTo(pm.hdc,x+width,y)
31 | LineTo(pm.hdc,x+width,y+height)
32 | LineTo(pm.hdc,x,y+height)
33 | LineTo(pm.hdc,x,y)
34 |
35 |
36 |
37 |
38 | }
39 |
40 | public func(MouseEventArgs e) onClick { onBtnClick.raise(e) }
41 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/BITMAP.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int bmType
3 | public int bmWidth
4 | public int bmHeight
5 | public int bmWidthBytes
6 | public shr bmPlanes
7 | public shr bmBitsPixel
8 | public PTR bmBits
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/ImageUtil.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HINSTANCE as PTR
2 | acknowledge HBITMAP as PTR
3 |
4 | import(ImageReference)
5 |
6 | dllref(User32,HINSTANCE,str,int,int,int,int) LoadImageA HBITMAP
7 |
8 | static public func(ImageReference imgref) bmpFromRef HBITMAP {
9 | HBITMAP bmp becomes LoadImageA(null,imgref.fileName,0,imgref.width,imgref.height,16)
10 | retn(bmp)
11 | }
12 |
13 | static public func(str fn,int width,int height) loadBitmap HBITMAP {
14 | HBITMAP bmp becomes LoadImageA(null,fn,0,width,height,16)
15 | retn(bmp)
16 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/Line.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int x
3 | public int y
4 | public int x0
5 | public int y0
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/PAINTSTRUCT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(Windows/Drawing/RECT)
3 | int hdc
4 | bool fErase
5 | RECT rcPaint
6 | bool fRestore
7 | bool fIncUpdate
8 | int res int res0 int res1 int res2 int res3 int res4 int res5 int res6
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/POINT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int x
3 | public int y
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/RECT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int left
3 | public int top
4 | public int right
5 | public int bottom
6 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/RECTF.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int left
3 | public int right
4 | public int top
5 | public int bottom
6 | public int brush
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/SIZE.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int cx
3 | public int cy
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Drawing/Shapes.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Drawing/RECT)
2 | import(Windows/Components/Rectangle)
3 | dllref(User32,RECT,RECT,RECT) IntersectRect bool
4 |
5 | pullable static RECT lastRectIntersection
6 |
7 | public static func(RECT r,RECT r0) areRectsIntersecting bool {
8 |
9 | if (lastRectIntersection,=,null) { lastRectIntersection becomes new(RECT) }
10 | retn(IntersectRect(lastRectIntersection,r,r0))
11 |
12 | }
13 |
14 | public static func(Rectangle r) toNativeRect RECT {
15 |
16 | RECT r0 becomes new(RECT)
17 | r0.left becomes r.x
18 | r0.right becomes r.x+r.width
19 | r0.top becomes r.y
20 | r0.bottom becomes r.y+r.height
21 | retn(r0)
22 |
23 | }
24 |
25 | public static func(int x,int y,int width,int height) createNativeRect RECT {
26 |
27 | RECT r0 becomes new(RECT)
28 | r0.left becomes x
29 | r0.right becomes x+width
30 | r0.top becomes y
31 | r0.bottom becomes y+height
32 | retn(r0)
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/ErrorHandler.sunset:
--------------------------------------------------------------------------------
1 | import(String)
2 | dllref(Kernel32) GetLastError int
3 | dllref(Kernel32,int,int,int,int,str,int,int#) FormatMessageA int
4 | dllref(User32,int,str,str,int) MessageBoxA int
5 | setpheapvar
6 |
7 | private static constant int bufferLength becomes 200h
8 | public static func getLastErrorCode int { retn(GetLastError) }
9 | public static func(int errorCode) errorCodeToString str {
10 |
11 | byte# buffer becomes #bufferLength
12 | int flags becomes 1200h ; FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS
13 | int lang becomes 400h ; LANG_NEUTRAL, SUBLANG_DEFAULT
14 | FormatMessageA(flags,null,errorCode,lang,buffer,bufferLength,null)
15 | retn(String.fromBytes(buffer))
16 |
17 | }
18 | public static func mboxLastError int {
19 |
20 | retn(MessageBoxA(0,errorCodeToString(getLastErrorCode),"An error has occurred",0))
21 |
22 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/FormEventArgs.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public str info
3 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/FormTimer.sunset:
--------------------------------------------------------------------------------
1 | ;dllref(User32,int,int) KillTimer bool
2 | public int id
3 | public int hwnd
4 | ; Return value: whether or not the function was successful
5 | public func destroy bool {
6 |
7 | ;retn(KillTimer(hwnd,id))
8 |
9 | }
10 |
11 | constructor(int _id,int hWnd) {
12 |
13 | id becomes _id
14 | hwnd becomes hWnd
15 |
16 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/GUID.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int Data1
3 | public shr Data2
4 | public shr Data3
5 | ; setStyle(Array,Static)
6 | ; public byte# Data4 becomes #8
7 | public int Data4
8 | public int Data5
9 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/KeyEventArgs.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(ASCIIKey)
3 | public ASCIIKey key
4 | public int flags
5 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/MSG.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(Windows/Drawing/POINT)
3 | int hwnd
4 | int message
5 | int wParam
6 | int lParam
7 | int time
8 | POINT point
9 | int lPrivate
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/MessageBox.sunset:
--------------------------------------------------------------------------------
1 | dllref(User32,int,str,str,int) stdcall:MessageBoxA int
2 | dllref(User32,str,str,int) cdecl:wsprintfA int
3 |
4 | private static str emptyString becomes ""
5 |
6 | ; MessageBox with no title
7 | public static func(str msg) mboxMessage int { retn(MessageBoxA(0,msg,emptyString,0)) }
8 |
9 | ; MessageBox with a number
10 | public static func(int num) mboxNumber int {
11 |
12 | str buffer becomes "-############" ; 32 bit number buffer
13 | str format becomes "%d"
14 | wsprintfA(buffer,format,num)
15 | MessageBoxA(null,buffer,emptyString,0)
16 |
17 | }
18 |
19 | ; MessageBox with native functionality
20 | public static func(int handle,str msg,str title,int flags) mboxNative int {
21 |
22 | retn(MessageBoxA(handle,msg,title,flags))
23 |
24 | }
25 |
26 | ; standard MessageBox with message and title
27 | public static func(str msg,str title) mbox int {
28 |
29 | retn(MessageBoxA(null,msg,title,0))
30 |
31 | }
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/MouseEventArgs.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int x
3 | public int y
4 | ;public bool lmb
5 | ;public bool rmb
6 | ;public bool mmb
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/AddressFamily.sunset:
--------------------------------------------------------------------------------
1 | ENUM
2 |
3 | UNSPEC,
4 | INET becomes 2,
5 | IPX becomes 6,
6 | APPLETALK becomes 16,
7 | NETBIOS becomes 17,
8 | INET6 becomes 23,
9 | IRDA becomes 26,
10 | BTH becomes 32
11 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/HOSTENT.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public str h_name
3 | public str# h_aliases
4 | shr h_addrtype
5 | shr h_length
6 | str# h_addr_list
7 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/IpProtocol.sunset:
--------------------------------------------------------------------------------
1 | ENUM
2 |
3 | UNSPECIFIED,
4 | ICMP,
5 | IGMP,
6 | RFCOMM,
7 | TCP becomes 6,
8 | UDP becomes 17,
9 | ICMPV6 becomes 58,
10 | RM becomes 113
11 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/SOCKADDR_IN:
--------------------------------------------------------------------------------
1 | STRUCT
2 |
3 | public shr sin_family ; temporary until structs can be made of shorts and etc (it's on my todo list) then I will change it to AddressFamily
4 | ; For now etc.sin_family becomes cast(AddressFamily.AF_INET,shr) can be done for example
5 |
6 | public shr sin_port
7 | public int sin_addr
8 |
9 | int resi int resi0
10 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/SocketType.sunset:
--------------------------------------------------------------------------------
1 | ENUM
2 |
3 | STREAM becomes 1,
4 | DGRAM,
5 | RAW,
6 | RDM,
7 | SEQPACKET
8 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/UDPClient.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Net/AddressFamily)
2 | import(Windows/Net/SocketType)
3 | import(Windows/Net/IpProtocol)
4 | import(Windows/Net/WSADATA)
5 | import(Windows/MessageBox)
6 | import(Windows/Net/SOCKADDR_IN)
7 | import(Windows/Net/WSAPROTOCOL_INFOA)
8 | import(String)
9 | dllref(Ws2_32,AddressFamily,SocketType,IpProtocol) socket int
10 | dllref(Ws2_32) WSAGetLastError int
11 | dllref(Ws2_32,shr,WSADATA) WSAStartup int
12 | dllref(Ws2_32,int) closesocket int
13 | dllref(Ws2_32,int,byte#,int,int,SOCKADDR_IN,int) sendto int
14 | dllref(Ws2_32,str,int,WSAPROTOCOL_INFOA,SOCKADDR_IN,PTR) WSAStringToAddressA int
15 | dllref(Ws2_32,int,byte#,int,int,SOCKADDR_IN,PTR) recvfrom int
16 |
17 | pullable int sockDesc
18 | pullable int lastError becomes 0
19 |
20 | private SOCKADDR_IN serverAddr
21 |
22 | public func(byte# data,int dataLen) send bool {
23 |
24 | sendto(sockDesc,data,dataLen+8,0,serverAddr,Bsizeof(SOCKADDR_IN))
25 |
26 | }
27 |
28 | public func close int {
29 | sockDesc becomes 0
30 | retn(closesocket(sockDesc))
31 | }
32 |
33 | public func getResponse byte# {
34 |
35 | byte# buffer becomes #1024
36 | int ln becomes Bsizeof(SOCKADDR_IN)
37 | int n becomes recvfrom(sockDesc,buffer,1024,0,serverAddr,$ln)
38 | retn(buffer)
39 |
40 | }
41 |
42 | constructor(str ip,shr port) {
43 |
44 | ; Initialize winsock
45 | ; https://learn.microsoft.com/en-us/windows/win32/winsock/initializing-winsock
46 | WSADATA wd becomes new(WSADATA)
47 | int res becomes WSAStartup(0202,wd)
48 | if (res,=/=,0) { lastError becomes res }
49 |
50 | sockDesc becomes socket(AddressFamily.INET,SocketType.DGRAM,IpProtocol.UDP)
51 | if (sockDesc,<,0) {
52 | ; Error (+ Invalid socket, no point continuing)
53 | lastError becomes WSAGetLastError
54 | }
55 | else {
56 | ; Socket OK
57 | serverAddr becomes new(SOCKADDR_IN)
58 | int len becomes Bsizeof(SOCKADDR_IN)
59 | WSAStringToAddressA(ip,AddressFamily.INET,null,serverAddr,$len)
60 | serverAddr.sin_family becomes cast(AddressFamily.INET,shr)
61 | serverAddr.sin_port becomes port
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/UDPServer.sunset:
--------------------------------------------------------------------------------
1 | import(Windows/Net/AddressFamily)
2 | import(Windows/Net/SocketType)
3 | import(Windows/Net/IpProtocol)
4 | import(Windows/Net/WSADATA)
5 | import(Windows/MessageBox)
6 | import(Windows/Net/SOCKADDR_IN)
7 | import(String)
8 | dllref(Ws2_32,AddressFamily,SocketType,IpProtocol) socket int
9 | dllref(Ws2_32) WSAGetLastError int
10 | dllref(Ws2_32,shr,WSADATA) WSAStartup int
11 | dllref(Ws2_32,int,SOCKADDR_IN,int) bind int
12 | dllref(Ws2_32,int,byte#,int,int,SOCKADDR_IN,PTR) recvfrom int
13 | dllref(Ws2_32,int) closesocket int
14 | dllref(Ws2_32,int,byte#,int,int,SOCKADDR_IN,int) sendto int
15 |
16 | pullable int sockDesc
17 | pullable int lastError becomes 0
18 |
19 | private SOCKADDR_IN serverAddr
20 | private SOCKADDR_IN lastClient
21 |
22 | public func listen byte# {
23 |
24 | byte# buffer becomes #1024
25 | int ln becomes Bsizeof(SOCKADDR_IN)
26 | SOCKADDR_IN clientAddr becomes new(SOCKADDR_IN)
27 | int n becomes recvfrom(sockDesc,buffer,1024,0,clientAddr,$ln)
28 | lastClient becomes clientAddr
29 | retn(buffer)
30 |
31 | }
32 |
33 | public func close int {
34 | sockDesc becomes 0
35 | retn(closesocket(sockDesc))
36 | }
37 |
38 | public func(byte# data,int dataLen) respond {
39 |
40 | sendto(sockDesc,data,dataLen+8,0,lastClient,Bsizeof(SOCKADDR_IN))
41 |
42 | }
43 |
44 | constructor(shr port) {
45 |
46 | ; Initialize winsock
47 | ; https://learn.microsoft.com/en-us/windows/win32/winsock/initializing-winsock
48 | WSADATA wd becomes new(WSADATA)
49 | int res becomes WSAStartup(0202,wd)
50 | if (res,=/=,0) { lastError becomes res }
51 |
52 | sockDesc becomes socket(AddressFamily.INET,SocketType.DGRAM,IpProtocol.UDP)
53 | if (sockDesc,<,0) {
54 | ; Error (+ Invalid socket, no point continuing)
55 | lastError becomes WSAGetLastError
56 | }
57 | else {
58 | ; Socket OK
59 | SOCKADDR_IN serverAddr becomes new(SOCKADDR_IN)
60 | serverAddr.sin_family becomes cast(AddressFamily.INET,shr)
61 | serverAddr.sin_port becomes port
62 |
63 | if (bind(sockDesc,serverAddr,Bsizeof(SOCKADDR_IN)),<,0) {
64 | ; Error
65 | lastError becomes WSAGetLastError
66 | }
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/WSADATA.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | shr wVersion
3 | shr wHighVersion
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/WSAPROTOCOLCHAIN.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int ChainLen
3 | public int# ChainEntries
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/Net/WSAPROTOCOL_INFOA.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(Windows/GUID)
3 | import(Windows/Net/WSAPROTOCOLCHAIN)
4 | public int dwServiceFlags1
5 | public int dwServiceFlags2
6 | public int dwServiceFlags3
7 | public int dwServiceFlags4
8 | public int dwProviderFlags
9 | public GUID ProviderId
10 | public int dwCatalogEntryId
11 | public WSAPROTOCOLCHAIN ProtocolChain
12 | public int iVersion
13 | public int iAddressFamily
14 | public int iMaxSockAddr
15 | public int iMinSockAddr
16 | public int iSocketType
17 | public int iProtocol
18 | public int iProtocolMaxOffset
19 | public int iNetworkByteOrder
20 | public int iSecurityScheme
21 | public int dwMessageSize
22 | public int dwProviderReserved
23 | public byte# szProtocol
24 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/PaintMsg.sunset:
--------------------------------------------------------------------------------
1 | acknowledge HDC as PTR
2 | acknowledge HWND as PTR
3 | STRUCT
4 | public HDC hdc
5 | public HWND windowHandle
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/SYSTEMTIME.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | shr wYear
3 | shr wMonth
4 | shr wDayOfWeek
5 | shr wDay
6 | shr wHour
7 | shr wMinute
8 | shr wSecond
9 | shr wMilliseconds
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/TimerEventArgs.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | import(Windows/FormTimer)
3 | public FormTimer sendingTimer
4 | public int formHandle
5 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/User.sunset:
--------------------------------------------------------------------------------
1 | dllref(Advapi32,str,int) GetUserNameA bool
2 | dllref(Kernel32) GetTickCount int
3 | dllref(User32,int,str,str,int) MessageBoxA int
4 | setpheapvar
5 |
6 | int UNLEN becomes 100h
7 | int nameLength becomes UNLEN
8 | str name becomes " "
9 |
10 | func getTicksSinceLoggedOn int { retn(GetTickCount) }
11 | func(str msg) userMbox int { retn(MessageBoxA(0,msg,name,0)) }
12 |
13 | GetUserNameA(name,$nameLength)
--------------------------------------------------------------------------------
/Sunset/bin/Debug/Windows/WNDCLASSA.sunset:
--------------------------------------------------------------------------------
1 | STRUCT
2 | public int style
3 | public FUNCPTR lpfnWndProc
4 | public int cbClsExtra
5 | public int cbWndExtra
6 | public int hInstance
7 | public int hIcon
8 | public int hCursor
9 | public int hbrBackground
10 | public str lpszMenuName
11 | public str lpszClassName
12 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/compile.bat:
--------------------------------------------------------------------------------
1 | :here
2 | pause
3 | @echo on
4 | cls
5 | sunset "C:\Users\usr\Documents\GitHub\Sunset\Sunset\bin\Debug\ComponentsTest.sunset"
6 | ComponentsTest
7 | @echo off
8 | goto :here
9 |
--------------------------------------------------------------------------------
/Sunset/bin/Debug/compile_bash:
--------------------------------------------------------------------------------
1 | exec & wine Sunset "/home/boss/NetPong/Server/Server.sunproj"
2 | exec & wine Sunset "/home/boss/NetPong/Player/Player.sunproj"
3 | exec & wine "/home/boss/NetPong/Server/bin/Server.exe"
4 |
--------------------------------------------------------------------------------
/Sunset/bin/Release/ProgrammingLanguageTutorialIdea.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Release/ProgrammingLanguageTutorialIdea.exe
--------------------------------------------------------------------------------
/Sunset/bin/Release/ProgrammingLanguageTutorialIdea.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Sunset/bin/Release/source.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Release/source.txt
--------------------------------------------------------------------------------
/Sunset/bin/Release/thing.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/bin/Release/thing.exe
--------------------------------------------------------------------------------
/Sunset/obj/Debug/.NETFramework,Version=v4.7.1.AssemblyAttributes.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using System.Reflection;
4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
5 |
--------------------------------------------------------------------------------
/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.csproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
1 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.exe.config
2 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.exe
3 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.pdb
4 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.csprojResolveAssemblyReference.cache
5 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.exe
6 | C:\Users\GDSPIOSJDGOSDHGJSDhg\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.pdb
7 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.exe.config
8 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.exe
9 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\bin\Debug\ProgrammingLanguageTutorialIdea.pdb
10 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.csprojResolveAssemblyReference.cache
11 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.exe
12 | C:\Users\usr\Documents\GitHub\ProgrammingLanguageTutorialIdea\ProgrammingLanguageTutorialIdea\obj\Debug\ProgrammingLanguageTutorialIdea.pdb
13 |
--------------------------------------------------------------------------------
/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.csprojResolveAssemblyReference.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.csprojResolveAssemblyReference.cache
--------------------------------------------------------------------------------
/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.exe
--------------------------------------------------------------------------------
/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/ProgrammingLanguageTutorialIdea.pdb
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.csproj.AssemblyReference.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/Sunset.csproj.AssemblyReference.cache
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.csproj.CoreCompileInputs.cache:
--------------------------------------------------------------------------------
1 | 3bd9cd878d582617b29614d9cec81d1095cf2c90
2 |
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.csproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
1 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/bin/Debug/Sunset.exe.config
2 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/bin/Debug/Sunset.exe
3 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/bin/Debug/Sunset.pdb
4 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/obj/Debug/Sunset.csprojResolveAssemblyReference.cache
5 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/obj/Debug/Sunset.exe
6 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/ProgrammingLanguageTutorialIdea/obj/Debug/Sunset.pdb
7 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/bin/Debug/Sunset.exe.config
8 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/bin/Debug/Sunset.exe
9 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/bin/Debug/Sunset.pdb
10 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/obj/Debug/Sunset.csprojResolveAssemblyReference.cache
11 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/obj/Debug/Sunset.exe
12 | C:/Users/usr/Documents/GitHub/ProgrammingLanguageTutorialIdea/Sunset/obj/Debug/Sunset.pdb
13 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.csprojResolveAssemblyReference.cache
14 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.exe
15 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.pdb
16 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe.config
17 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe
18 | C:/Users/usr/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.pdb
19 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.csprojResolveAssemblyReference.cache
20 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe.config
21 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe
22 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/bin/Debug/Sunset.pdb
23 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.exe
24 | C:/Users/GDSPIOSJDGOSDHGJSDhg/Documents/GitHub/Sunset/Sunset/obj/Debug/Sunset.pdb
25 | /home/boss/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe.config
26 | /home/boss/GitHub/Sunset/Sunset/bin/Debug/Sunset.exe
27 | /home/boss/GitHub/Sunset/Sunset/bin/Debug/Sunset.pdb
28 | /home/boss/GitHub/Sunset/Sunset/obj/Debug/Sunset.csproj.AssemblyReference.cache
29 | /home/boss/GitHub/Sunset/Sunset/obj/Debug/Sunset.csproj.CoreCompileInputs.cache
30 | /home/boss/GitHub/Sunset/Sunset/obj/Debug/Sunset.exe
31 | /home/boss/GitHub/Sunset/Sunset/obj/Debug/Sunset.pdb
32 |
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.csprojResolveAssemblyReference.cache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/Sunset.csprojResolveAssemblyReference.cache
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/Sunset.exe
--------------------------------------------------------------------------------
/Sunset/obj/Debug/Sunset.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/Sunset.pdb
--------------------------------------------------------------------------------
/Sunset/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
--------------------------------------------------------------------------------
/Sunset/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
--------------------------------------------------------------------------------
/Sunset/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakefrey0/Sunset/19ae387278d0251c144e6ac9d56ba2eed88e5046/Sunset/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
--------------------------------------------------------------------------------