├── .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 | ![Syntax example](https://github.com/cashsignsesh/Sunset/blob/main/Sunset/bin/Debug/Capture.PNG) 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 --------------------------------------------------------------------------------