Compare commits
No commits in common. "master" and "develop" have entirely different histories.
124
.gitignore
vendored
124
.gitignore
vendored
|
@ -9,6 +9,7 @@ picoc
|
||||||
build/*
|
build/*
|
||||||
archives/
|
archives/
|
||||||
|
|
||||||
|
CMakeLists.txt
|
||||||
picoc.plist
|
picoc.plist
|
||||||
picoc.config
|
picoc.config
|
||||||
picoc.creator
|
picoc.creator
|
||||||
|
@ -20,125 +21,4 @@ tests/fred.txt
|
||||||
analysis.txt
|
analysis.txt
|
||||||
gmon.out
|
gmon.out
|
||||||
tests/gmon.out
|
tests/gmon.out
|
||||||
|
.idea/
|
||||||
# Created by https://www.gitignore.io/api/macos,clion
|
|
||||||
# Edit at https://www.gitignore.io/?templates=macos,clion
|
|
||||||
|
|
||||||
|
|
||||||
### CLion ###
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### CLion Patch ###
|
|
||||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
|
||||||
|
|
||||||
# *.iml
|
|
||||||
# modules.xml
|
|
||||||
# .idea/misc.xml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# Sonarlint plugin
|
|
||||||
.idea/**/sonarlint/
|
|
||||||
|
|
||||||
# SonarQube Plugin
|
|
||||||
.idea/**/sonarIssues.xml
|
|
||||||
|
|
||||||
# Markdown Navigator plugin
|
|
||||||
.idea/**/markdown-navigator.xml
|
|
||||||
.idea/**/markdown-navigator/
|
|
||||||
|
|
||||||
### macOS ###
|
|
||||||
# General
|
|
||||||
.DS_Store
|
|
||||||
.AppleDouble
|
|
||||||
.LSOverride
|
|
||||||
|
|
||||||
# Icon must end with two \r
|
|
||||||
Icon
|
|
||||||
|
|
||||||
# Thumbnails
|
|
||||||
._*
|
|
||||||
|
|
||||||
# Files that might appear in the root of a volume
|
|
||||||
.DocumentRevisions-V100
|
|
||||||
.fseventsd
|
|
||||||
.Spotlight-V100
|
|
||||||
.TemporaryItems
|
|
||||||
.Trashes
|
|
||||||
.VolumeIcon.icns
|
|
||||||
.com.apple.timemachine.donotpresent
|
|
||||||
|
|
||||||
# Directories potentially created on remote AFP share
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
|
|
||||||
# End of https://www.gitignore.io/api/macos,clion
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
|
||||||
<component name="JavaScriptSettings">
|
|
||||||
<option name="languageLevel" value="ES6" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/picoc.iml" filepath="$PROJECT_DIR$/.idea/picoc.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,2 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc basic.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="basic.c" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc complete.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="complete.c" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc expressions.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="expressions.c" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc factorial.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="factorial.c - 5" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc loop.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="loop.c" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="picoc md5.c" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="md5.c - "test"" REDIRECT_INPUT="false" WORKING_DIR="file://$ProjectFileDir$/c-tests" PASS_PARENT_ENVS_2="true" PROJECT_NAME="picoc" TARGET_NAME="picoc" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="picoc" RUN_TARGET_NAME="picoc">
|
|
||||||
<method v="2">
|
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,47 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.15)
|
|
||||||
project(picoc C)
|
|
||||||
|
|
||||||
execute_process(COMMAND git show-ref --abbrev=8 --head --hash head OUTPUT_VARIABLE hash OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
execute_process(COMMAND git describe --abbrev=0 --tags OUTPUT_VARIABLE tag OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
message("${tag} ${hash}")
|
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
|
||||||
set(CMAKE_C_COMPILER gcc)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic")
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES m readline)
|
|
||||||
add_definitions(-DUNIX_HOST -DVER="${hash}" -DTAG="${tag}")
|
|
||||||
#add_definitions(-DDEBUG_EXPRESSIONS)
|
|
||||||
|
|
||||||
include_directories(.)
|
|
||||||
|
|
||||||
add_executable(picoc
|
|
||||||
cstdlib/ctype.c
|
|
||||||
cstdlib/errno.c
|
|
||||||
cstdlib/math.c
|
|
||||||
cstdlib/stdbool.c
|
|
||||||
cstdlib/stdio.c
|
|
||||||
cstdlib/stdlib.c
|
|
||||||
cstdlib/string.c
|
|
||||||
cstdlib/time.c
|
|
||||||
cstdlib/unistd.c
|
|
||||||
platform/library_unix.c
|
|
||||||
platform/platform_unix.c
|
|
||||||
clibrary.c
|
|
||||||
debug.c
|
|
||||||
expression.c
|
|
||||||
heap.c
|
|
||||||
include.c
|
|
||||||
interpreter.h
|
|
||||||
lex.c
|
|
||||||
parse.c
|
|
||||||
picoc.c
|
|
||||||
picoc.h
|
|
||||||
platform.c
|
|
||||||
platform.h
|
|
||||||
stats.c
|
|
||||||
stats.h
|
|
||||||
table.c
|
|
||||||
type.c
|
|
||||||
variable.c)
|
|
||||||
|
|
||||||
target_link_libraries(picoc -lm -lreadline)
|
|
5
Makefile
5
Makefile
|
@ -12,7 +12,7 @@ LIBS=-lm -lreadline
|
||||||
|
|
||||||
TARGET = picoc
|
TARGET = picoc
|
||||||
SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c \
|
SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c \
|
||||||
variable.c clibrary.c platform.c include.c debug.c stats.c \
|
variable.c clibrary.c platform.c include.c debug.c \
|
||||||
platform/platform_unix.c platform/library_unix.c \
|
platform/platform_unix.c platform/library_unix.c \
|
||||||
cstdlib/stdio.c cstdlib/math.c cstdlib/string.c cstdlib/stdlib.c \
|
cstdlib/stdio.c cstdlib/math.c cstdlib/string.c cstdlib/stdlib.c \
|
||||||
cstdlib/time.c cstdlib/errno.c cstdlib/ctype.c cstdlib/stdbool.c \
|
cstdlib/time.c cstdlib/errno.c cstdlib/ctype.c cstdlib/stdbool.c \
|
||||||
|
@ -34,7 +34,7 @@ clean:
|
||||||
|
|
||||||
count:
|
count:
|
||||||
@echo "Core:"
|
@echo "Core:"
|
||||||
@cat picoc.h interpreter.h picoc.c table.c lex.c parse.c expression.c platform.c heap.c type.c variable.c include.c debug.c stats.c | grep -v '^[ ]*/\*' | grep -v '^[ ]*$$' | wc
|
@cat picoc.h interpreter.h picoc.c table.c lex.c parse.c expression.c platform.c heap.c type.c variable.c include.c debug.c | grep -v '^[ ]*/\*' | grep -v '^[ ]*$$' | wc
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Everything:"
|
@echo "Everything:"
|
||||||
@cat $(SRCS) *.h */*.h | wc
|
@cat $(SRCS) *.h */*.h | wc
|
||||||
|
@ -53,7 +53,6 @@ clibrary.o: clibrary.c picoc.h interpreter.h platform.h
|
||||||
platform.o: platform.c picoc.h interpreter.h platform.h
|
platform.o: platform.c picoc.h interpreter.h platform.h
|
||||||
include.o: include.c picoc.h interpreter.h platform.h
|
include.o: include.c picoc.h interpreter.h platform.h
|
||||||
debug.o: debug.c interpreter.h platform.h
|
debug.o: debug.c interpreter.h platform.h
|
||||||
stats.o: stats.c stats.h interpreter.h platform.h
|
|
||||||
platform/platform_unix.o: platform/platform_unix.c picoc.h interpreter.h platform.h
|
platform/platform_unix.o: platform/platform_unix.c picoc.h interpreter.h platform.h
|
||||||
platform/library_unix.o: platform/library_unix.c interpreter.h platform.h
|
platform/library_unix.o: platform/library_unix.c interpreter.h platform.h
|
||||||
cstdlib/stdio.o: cstdlib/stdio.c interpreter.h platform.h
|
cstdlib/stdio.o: cstdlib/stdio.c interpreter.h platform.h
|
||||||
|
|
|
@ -327,7 +327,7 @@ void PlatformLibraryInit()
|
||||||
/* define an example structure */
|
/* define an example structure */
|
||||||
Tokens = LexAnalyse(IntrinsicName, StructDefinition, strlen(StructDefinition), NULL);
|
Tokens = LexAnalyse(IntrinsicName, StructDefinition, strlen(StructDefinition), NULL);
|
||||||
LexInitParser(&Parser, StructDefinition, Tokens, IntrinsicName, true, false);
|
LexInitParser(&Parser, StructDefinition, Tokens, IntrinsicName, true, false);
|
||||||
TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic, &IsExtern, &IsVolatile);
|
TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic);
|
||||||
HeapFree(Tokens);
|
HeapFree(Tokens);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
2
c-tests/.gitignore
vendored
2
c-tests/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
*
|
|
||||||
!*.*
|
|
|
@ -1,7 +0,0 @@
|
||||||
int a, b;
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
a = 1 + 2;
|
|
||||||
b = a + 3;
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
typedef int int_type;
|
|
||||||
|
|
||||||
struct a_struct {
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
};
|
|
||||||
|
|
||||||
union a_union {
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma a_pragma
|
|
||||||
|
|
||||||
int a;
|
|
||||||
unsigned long b = 0;
|
|
||||||
int *c;
|
|
||||||
char arr[5] = "test";
|
|
||||||
|
|
||||||
int dbl(int a, ...) {
|
|
||||||
return a * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
a = 1 + 2;
|
|
||||||
b = dbl(a);
|
|
||||||
|
|
||||||
if (a < 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (0) {
|
|
||||||
a++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
a--;
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
a += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
lab: a = 1;
|
|
||||||
goto lab;
|
|
||||||
|
|
||||||
struct a_struct s;
|
|
||||||
struct a_struct *sp = &s;
|
|
||||||
s.a = 1;
|
|
||||||
sp->b = 2;
|
|
||||||
|
|
||||||
switch (a) {
|
|
||||||
case 1:
|
|
||||||
b = 1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
b = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
b = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a = b ? 1 : 2;
|
|
||||||
|
|
||||||
a += (int)10;
|
|
||||||
|
|
||||||
for(;;);
|
|
||||||
|
|
||||||
int c = a, b;
|
|
||||||
|
|
||||||
return 0, 1;
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
int b, c;
|
|
||||||
int d[2];
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int a = 1 + 2;
|
|
||||||
b = a + 3 + 4 + 5;
|
|
||||||
c = (a * b++ + 6 - 7) / 8;
|
|
||||||
a += 1;
|
|
||||||
b++;
|
|
||||||
a = b + c;
|
|
||||||
d[0] = 1;
|
|
||||||
// *(d + 1) = 2;
|
|
||||||
// return a = 1, b = 2;
|
|
||||||
return a = 1;
|
|
||||||
|
|
||||||
a = b++;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
int a;
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
a = 1;
|
|
||||||
decrement();
|
|
||||||
return a + b;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
extern int a;
|
|
||||||
extern long b;
|
|
||||||
|
|
||||||
//void decrement();
|
|
|
@ -1,8 +0,0 @@
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
long b = 1;
|
|
||||||
|
|
||||||
void decrement() {
|
|
||||||
a--;
|
|
||||||
b--;
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int in = atoi(argv[1]);
|
|
||||||
int fact = 1;
|
|
||||||
|
|
||||||
for (int i = 1; i <= in; i++) {
|
|
||||||
fact *= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%d factorial is %d", in, fact);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
202
c-tests/hash.c
202
c-tests/hash.c
|
@ -1,202 +0,0 @@
|
||||||
/*
|
|
||||||
** C implementation of a hash table ADT
|
|
||||||
*/
|
|
||||||
|
|
||||||
//typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
|
|
||||||
#define SUCCESS 0
|
|
||||||
#define FAIL 1
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct tagEntry
|
|
||||||
{
|
|
||||||
char* key;
|
|
||||||
char* value;
|
|
||||||
} Entry;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct tagNode
|
|
||||||
{
|
|
||||||
Entry* entry;
|
|
||||||
|
|
||||||
struct tagNode* next;
|
|
||||||
} Node;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct tagHash
|
|
||||||
{
|
|
||||||
unsigned int table_size;
|
|
||||||
|
|
||||||
Node** heads;
|
|
||||||
|
|
||||||
} Hash;
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned int hash_func(char* str, unsigned int table_size)
|
|
||||||
{
|
|
||||||
unsigned int hash_value;
|
|
||||||
unsigned int a = 127;
|
|
||||||
|
|
||||||
for (hash_value = 0; *str != 0; ++str)
|
|
||||||
hash_value = (a*hash_value + *str) % table_size;
|
|
||||||
|
|
||||||
return hash_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int HashCreate(Hash** hash, unsigned int table_size)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (table_size < 1)
|
|
||||||
return FAIL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate space for the Hash
|
|
||||||
*/
|
|
||||||
if (((*hash) = malloc(sizeof(**hash))) == NULL)
|
|
||||||
return FAIL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate space for the array of list heads
|
|
||||||
*/
|
|
||||||
if (((*hash)->heads = malloc(table_size*sizeof(*((*hash)->heads)))) == NULL)
|
|
||||||
return FAIL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize Hash info
|
|
||||||
*/
|
|
||||||
for (i = 0; i < table_size; ++i)
|
|
||||||
{
|
|
||||||
(*hash)->heads[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*hash)->table_size = table_size;
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int HashInsert(Hash* hash, Entry* entry)
|
|
||||||
{
|
|
||||||
unsigned int index = hash_func(entry->key, hash->table_size);
|
|
||||||
Node* temp = hash->heads[index];
|
|
||||||
|
|
||||||
HashRemove(hash, entry->key);
|
|
||||||
|
|
||||||
if ((hash->heads[index] = malloc(sizeof(Node))) == NULL)
|
|
||||||
return FAIL;
|
|
||||||
|
|
||||||
hash->heads[index]->entry = malloc(sizeof(Entry));
|
|
||||||
hash->heads[index]->entry->key = malloc(strlen(entry->key)+1);
|
|
||||||
hash->heads[index]->entry->value = malloc(strlen(entry->value)+1);
|
|
||||||
strcpy(hash->heads[index]->entry->key, entry->key);
|
|
||||||
strcpy(hash->heads[index]->entry->value, entry->value);
|
|
||||||
|
|
||||||
hash->heads[index]->next = temp;
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Entry* HashFind(Hash* hash, char* key)
|
|
||||||
{
|
|
||||||
unsigned int index = hash_func(key, hash->table_size);
|
|
||||||
Node* temp = hash->heads[index];
|
|
||||||
|
|
||||||
while (temp != NULL)
|
|
||||||
{
|
|
||||||
if (!strcmp(key, temp->entry->key))
|
|
||||||
return temp->entry;
|
|
||||||
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int HashRemove(Hash* hash, char* key)
|
|
||||||
{
|
|
||||||
unsigned int index = hash_func(key, hash->table_size);
|
|
||||||
Node* temp1 = hash->heads[index];
|
|
||||||
Node* temp2 = temp1;
|
|
||||||
|
|
||||||
while (temp1 != NULL)
|
|
||||||
{
|
|
||||||
if (!strcmp(key, temp1->entry->key))
|
|
||||||
{
|
|
||||||
if (temp1 == hash->heads[index])
|
|
||||||
hash->heads[index] = hash->heads[index]->next;
|
|
||||||
else
|
|
||||||
temp2->next = temp1->next;
|
|
||||||
|
|
||||||
free(temp1->entry->key);
|
|
||||||
free(temp1->entry->value);
|
|
||||||
free(temp1->entry);
|
|
||||||
free(temp1);
|
|
||||||
temp1 = NULL;
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp2 = temp1;
|
|
||||||
temp1 = temp1->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (hash == NULL || hash->heads == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < hash->table_size; ++i)
|
|
||||||
{
|
|
||||||
Node* temp = hash->heads[i];
|
|
||||||
|
|
||||||
while (temp != NULL)
|
|
||||||
{
|
|
||||||
PrintFunc(temp->entry->key, temp->entry->value);
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HashDestroy(Hash* hash)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (hash == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < hash->table_size; ++i)
|
|
||||||
{
|
|
||||||
Node* temp = hash->heads[i];
|
|
||||||
|
|
||||||
while (temp != NULL)
|
|
||||||
{
|
|
||||||
Node* temp2 = temp;
|
|
||||||
|
|
||||||
free(temp->entry->key);
|
|
||||||
free(temp->entry->value);
|
|
||||||
free(temp->entry);
|
|
||||||
|
|
||||||
temp = temp->next;
|
|
||||||
|
|
||||||
free(temp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(hash->heads);
|
|
||||||
hash->heads = NULL;
|
|
||||||
|
|
||||||
free(hash);
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int i = 123;
|
|
||||||
int j = 456;
|
|
||||||
int k = 0;
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < 2; i++, j++) {
|
|
||||||
k += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return k - (j * 2);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int j = 999;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
j = i - 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return j;
|
|
||||||
}
|
|
175
c-tests/md5.c
175
c-tests/md5.c
|
@ -1,175 +0,0 @@
|
||||||
/*
|
|
||||||
* Simple MD5 implementation
|
|
||||||
*
|
|
||||||
* Compile with: gcc -o md5 md5.c
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
// #include <stdint.h>
|
|
||||||
|
|
||||||
// Mostly ok, but not as a function return type for some reason
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef unsigned int size_t;
|
|
||||||
|
|
||||||
// Constants are the integer part of the sines of integers (in radians) * 2^32.
|
|
||||||
uint32_t k[64] = {
|
|
||||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
|
|
||||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
|
|
||||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
|
|
||||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
|
|
||||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
|
|
||||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
|
|
||||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
|
|
||||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
|
|
||||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
|
|
||||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
|
|
||||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
|
|
||||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
|
|
||||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
|
|
||||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
|
|
||||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
|
|
||||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
|
|
||||||
|
|
||||||
// r specifies the per-round shift amounts
|
|
||||||
uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
|
||||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
|
||||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
|
||||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
|
||||||
|
|
||||||
unsigned int left_rotate(uint32_t x, uint32_t c) {
|
|
||||||
return (x << c) | (x >> (32 - c));
|
|
||||||
}
|
|
||||||
|
|
||||||
void to_bytes(uint32_t val, uint8_t *bytes)
|
|
||||||
{
|
|
||||||
bytes[0] = (uint8_t) val;
|
|
||||||
bytes[1] = (uint8_t) (val >> 8);
|
|
||||||
bytes[2] = (uint8_t) (val >> 16);
|
|
||||||
bytes[3] = (uint8_t) (val >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int to_int32(uint8_t *bytes)
|
|
||||||
{
|
|
||||||
return (uint32_t) bytes[0]
|
|
||||||
| ((uint32_t) bytes[1] << 8)
|
|
||||||
| ((uint32_t) bytes[2] << 16)
|
|
||||||
| ((uint32_t) bytes[3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5(uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {
|
|
||||||
|
|
||||||
// These vars will contain the hash
|
|
||||||
uint32_t h0, h1, h2, h3;
|
|
||||||
|
|
||||||
// Message (to prepare)
|
|
||||||
uint8_t *msg = NULL;
|
|
||||||
|
|
||||||
size_t new_len, offset;
|
|
||||||
uint32_t w[16];
|
|
||||||
uint32_t a, b, c, d, i, f, g, temp;
|
|
||||||
|
|
||||||
// Initialize variables - simple count in nibbles:
|
|
||||||
h0 = 0x67452301;
|
|
||||||
h1 = 0xefcdab89;
|
|
||||||
h2 = 0x98badcfe;
|
|
||||||
h3 = 0x10325476;
|
|
||||||
|
|
||||||
//Pre-processing:
|
|
||||||
//append "1" bit to message
|
|
||||||
//append "0" bits until message length in bits ≡ 448 (mod 512)
|
|
||||||
//append length mod (2^64) to message
|
|
||||||
|
|
||||||
for (new_len = initial_len + 1; new_len % (512/8) != 448/8; new_len++);
|
|
||||||
|
|
||||||
msg = malloc(new_len + 8);
|
|
||||||
memcpy(msg, initial_msg, initial_len);
|
|
||||||
msg[initial_len] = 0x80; // append the "1" bit; most significant bit is "first"
|
|
||||||
for (offset = initial_len + 1; offset < new_len; offset++)
|
|
||||||
msg[offset] = 0; // append "0" bits
|
|
||||||
|
|
||||||
// append the len in bits at the end of the buffer.
|
|
||||||
to_bytes(initial_len*8, msg + new_len);
|
|
||||||
// initial_len>>29 == initial_len*8>>32, but avoids overflow.
|
|
||||||
to_bytes(initial_len>>29, msg + new_len + 4);
|
|
||||||
|
|
||||||
// Process the message in successive 512-bit chunks:
|
|
||||||
//for each 512-bit chunk of message:
|
|
||||||
for(offset=0; offset<new_len; offset += (512/8)) {
|
|
||||||
|
|
||||||
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
w[i] = to_int32(msg + offset + i*4);
|
|
||||||
|
|
||||||
// Initialize hash value for this chunk:
|
|
||||||
a = h0;
|
|
||||||
b = h1;
|
|
||||||
c = h2;
|
|
||||||
d = h3;
|
|
||||||
|
|
||||||
// Main loop:
|
|
||||||
for(i = 0; i<64; i++) {
|
|
||||||
|
|
||||||
if (i < 16) {
|
|
||||||
f = (b & c) | ((~b) & d);
|
|
||||||
g = i;
|
|
||||||
} else if (i < 32) {
|
|
||||||
f = (d & b) | ((~d) & c);
|
|
||||||
g = (5*i + 1) % 16;
|
|
||||||
} else if (i < 48) {
|
|
||||||
f = b ^ c ^ d;
|
|
||||||
g = (3*i + 5) % 16;
|
|
||||||
} else {
|
|
||||||
f = c ^ (b | (~d));
|
|
||||||
g = (7*i) % 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = d;
|
|
||||||
d = c;
|
|
||||||
c = b;
|
|
||||||
b = b + left_rotate((a + f + k[i] + w[g]), r[i]);
|
|
||||||
a = temp;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this chunk's hash to result so far:
|
|
||||||
h0 += a;
|
|
||||||
h1 += b;
|
|
||||||
h2 += c;
|
|
||||||
h3 += d;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
free(msg);
|
|
||||||
|
|
||||||
//var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
|
|
||||||
to_bytes(h0, digest);
|
|
||||||
to_bytes(h1, digest + 4);
|
|
||||||
to_bytes(h2, digest + 8);
|
|
||||||
to_bytes(h3, digest + 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
char *msg = argv[1];
|
|
||||||
size_t len;
|
|
||||||
int i;
|
|
||||||
uint8_t result[16];
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
printf("usage: %s 'string'\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(msg);
|
|
||||||
|
|
||||||
md5((uint8_t*)msg, len, result);
|
|
||||||
|
|
||||||
// display result
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
printf("%2.2x", result[i]);
|
|
||||||
puts("");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
int a;
|
|
||||||
|
|
||||||
#pragma test1
|
|
||||||
|
|
||||||
int b;
|
|
||||||
|
|
||||||
_Pragma( "test2" )
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
a = 0;
|
|
||||||
|
|
||||||
#pragma test3
|
|
||||||
|
|
||||||
b = 1;
|
|
||||||
|
|
||||||
_Pragma("test4")
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
int a = 1;
|
|
||||||
int b = 2;
|
|
||||||
int c = a + b;
|
|
||||||
|
|
||||||
printf("%d\n", c);
|
|
|
@ -1,27 +0,0 @@
|
||||||
int a;
|
|
||||||
|
|
||||||
unsigned b;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
long d;
|
|
||||||
long int e;
|
|
||||||
unsigned long f;
|
|
||||||
unsigned long int g;
|
|
||||||
|
|
||||||
short h;
|
|
||||||
short int i;
|
|
||||||
unsigned short j;
|
|
||||||
unsigned short int k;
|
|
||||||
|
|
||||||
volatile int l;
|
|
||||||
int volatile static m;
|
|
||||||
|
|
||||||
const int x;
|
|
||||||
long const y;
|
|
||||||
|
|
||||||
typedef int MyInt;
|
|
||||||
MyInt z = 1;
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -46,7 +46,7 @@ void LibraryAdd(Picoc *pc, struct LibraryFunction *FuncList)
|
||||||
strlen((char*)FuncList[Count].Prototype), NULL);
|
strlen((char*)FuncList[Count].Prototype), NULL);
|
||||||
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens,
|
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens,
|
||||||
IntrinsicName, true, false);
|
IntrinsicName, true, false);
|
||||||
TypeParse(&Parser, &ReturnType, &Identifier, NULL, NULL, NULL);
|
TypeParse(&Parser, &ReturnType, &Identifier, NULL);
|
||||||
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
|
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
|
||||||
NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func;
|
NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func;
|
||||||
HeapFreeMem(pc, Tokens);
|
HeapFreeMem(pc, Tokens);
|
||||||
|
|
|
@ -100,7 +100,7 @@ void UnistdFchdir(struct ParseState *Parser, struct Value *ReturnValue,
|
||||||
void UnistdFdatasync(struct ParseState *Parser, struct Value *ReturnValue,
|
void UnistdFdatasync(struct ParseState *Parser, struct Value *ReturnValue,
|
||||||
struct Value **Param, int NumArgs)
|
struct Value **Param, int NumArgs)
|
||||||
{
|
{
|
||||||
#ifdef F_FULLFSYNC
|
#ifdef F_FULLSYNC
|
||||||
/* Mac OS X equivalent */
|
/* Mac OS X equivalent */
|
||||||
ReturnValue->Val->Integer = fcntl(Param[0]->Val->Integer, F_FULLFSYNC);
|
ReturnValue->Val->Integer = fcntl(Param[0]->Val->Integer, F_FULLFSYNC);
|
||||||
#else
|
#else
|
||||||
|
@ -331,13 +331,11 @@ void UnistdRmdir(struct ParseState *Parser, struct Value *ReturnValue,
|
||||||
ReturnValue->Val->Integer = rmdir(Param[0]->Val->Pointer);
|
ReturnValue->Val->Integer = rmdir(Param[0]->Val->Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void UnistdSbrk(struct ParseState *Parser, struct Value *ReturnValue,
|
void UnistdSbrk(struct ParseState *Parser, struct Value *ReturnValue,
|
||||||
struct Value **Param, int NumArgs)
|
struct Value **Param, int NumArgs)
|
||||||
{
|
{
|
||||||
ReturnValue->Val->Pointer = sbrk(Param[0]->Val->Integer);
|
ReturnValue->Val->Pointer = sbrk(Param[0]->Val->Integer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void UnistdSetgid(struct ParseState *Parser, struct Value *ReturnValue,
|
void UnistdSetgid(struct ParseState *Parser, struct Value *ReturnValue,
|
||||||
struct Value **Param, int NumArgs)
|
struct Value **Param, int NumArgs)
|
||||||
|
@ -560,7 +558,7 @@ struct LibraryFunction UnistdFunctions[] =
|
||||||
{UnistdRead, "ssize_t read(int, void*, size_t);"},
|
{UnistdRead, "ssize_t read(int, void*, size_t);"},
|
||||||
{UnistdReadlink, "int readlink(char*, char*, size_t);"},
|
{UnistdReadlink, "int readlink(char*, char*, size_t);"},
|
||||||
{UnistdRmdir, "int rmdir(char*);"},
|
{UnistdRmdir, "int rmdir(char*);"},
|
||||||
/* {UnistdSbrk, "void *sbrk(intptr_t);"}, */
|
{UnistdSbrk, "void *sbrk(intptr_t);"},
|
||||||
{UnistdSetgid, "int setgid(gid_t);"},
|
{UnistdSetgid, "int setgid(gid_t);"},
|
||||||
{UnistdSetpgid, "int setpgid(pid_t, pid_t);"},
|
{UnistdSetpgid, "int setpgid(pid_t, pid_t);"},
|
||||||
{UnistdSetpgrp, "pid_t setpgrp(void);"},
|
{UnistdSetpgrp, "pid_t setpgrp(void);"},
|
||||||
|
|
10
expression.c
10
expression.c
|
@ -1,7 +1,6 @@
|
||||||
/* picoc expression evaluator - a stack-based expression evaluation system
|
/* picoc expression evaluator - a stack-based expression evaluation system
|
||||||
* which handles operator precedence */
|
* which handles operator precedence */
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "stats.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* whether evaluation is left to right for a given precedence level */
|
/* whether evaluation is left to right for a given precedence level */
|
||||||
|
@ -1444,9 +1443,6 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
|
|
||||||
ParserCopy(&PreState, Parser);
|
ParserCopy(&PreState, Parser);
|
||||||
Token = LexGetToken(Parser, &LexValue, true);
|
Token = LexGetToken(Parser, &LexValue, true);
|
||||||
|
|
||||||
stats_log_expression(Token, Parser);
|
|
||||||
|
|
||||||
if ((((int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) ||
|
if ((((int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) ||
|
||||||
(Token == TokenCloseBracket && BracketPrecedence != 0)) &&
|
(Token == TokenCloseBracket && BracketPrecedence != 0)) &&
|
||||||
(Token != TokenColon || TernaryDepth > 0)) {
|
(Token != TokenColon || TernaryDepth > 0)) {
|
||||||
|
@ -1469,7 +1465,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
char *CastIdentifier;
|
char *CastIdentifier;
|
||||||
struct Value *CastTypeValue;
|
struct Value *CastTypeValue;
|
||||||
|
|
||||||
TypeParse(Parser, &CastType, &CastIdentifier, NULL, NULL, NULL);
|
TypeParse(Parser, &CastType, &CastIdentifier, NULL);
|
||||||
if (LexGetToken(Parser, &LexValue, true) != TokenCloseBracket)
|
if (LexGetToken(Parser, &LexValue, true) != TokenCloseBracket)
|
||||||
ProgramFail(Parser, "brackets not closed");
|
ProgramFail(Parser, "brackets not closed");
|
||||||
|
|
||||||
|
@ -1668,7 +1664,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
|
|
||||||
PrefixState = false;
|
PrefixState = false;
|
||||||
ParserCopy(Parser, &PreState);
|
ParserCopy(Parser, &PreState);
|
||||||
TypeParse(Parser, &Typ, &Identifier, NULL, NULL, NULL);
|
TypeParse(Parser, &Typ, &Identifier, NULL);
|
||||||
TypeValue = VariableAllocValueFromType(Parser->pc, Parser,
|
TypeValue = VariableAllocValueFromType(Parser->pc, Parser,
|
||||||
&Parser->pc->TypeType, false, NULL, false);
|
&Parser->pc->TypeType, false, NULL, false);
|
||||||
TypeValue->Val->Typ = Typ;
|
TypeValue->Val->Typ = Typ;
|
||||||
|
@ -1892,7 +1888,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser,
|
||||||
|
|
||||||
Parser->ScopeID = OldScopeID;
|
Parser->ScopeID = OldScopeID;
|
||||||
|
|
||||||
if (ParseStatement(&FuncParser, true, false) != ParseResultOk)
|
if (ParseStatement(&FuncParser, true) != ParseResultOk)
|
||||||
ProgramFail(&FuncParser, "function body expected");
|
ProgramFail(&FuncParser, "function body expected");
|
||||||
|
|
||||||
if (RunIt) {
|
if (RunIt) {
|
||||||
|
|
|
@ -174,11 +174,7 @@ enum LexToken {
|
||||||
/* 0x5c */ TokenEOF,
|
/* 0x5c */ TokenEOF,
|
||||||
TokenEndOfLine,
|
TokenEndOfLine,
|
||||||
TokenEndOfFunction,
|
TokenEndOfFunction,
|
||||||
TokenBackSlash,
|
TokenBackSlash
|
||||||
TokenVolatileType,
|
|
||||||
TokenHashPragma,
|
|
||||||
TokenUnderscorePragma,
|
|
||||||
TokenConstType
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* used in dynamic memory allocation */
|
/* used in dynamic memory allocation */
|
||||||
|
@ -512,9 +508,6 @@ struct Picoc_Struct {
|
||||||
struct Table StringTable;
|
struct Table StringTable;
|
||||||
struct TableEntry *StringHashTable[STRING_TABLE_SIZE];
|
struct TableEntry *StringHashTable[STRING_TABLE_SIZE];
|
||||||
char *StrEmpty;
|
char *StrEmpty;
|
||||||
|
|
||||||
/* stats */
|
|
||||||
int CollectStats;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* table.c */
|
/* table.c */
|
||||||
|
@ -554,7 +547,7 @@ extern void LexInteractiveStatementPrompt(Picoc *pc);
|
||||||
* void PicocParseInteractive(); */
|
* void PicocParseInteractive(); */
|
||||||
extern void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger);
|
extern void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger);
|
||||||
extern enum ParseResult ParseStatement(struct ParseState *Parser,
|
extern enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
int CheckTrailingSemicolon, int DoNotConsumeTrailingSemicolon);
|
int CheckTrailingSemicolon);
|
||||||
extern struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
extern struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
||||||
struct ValueType *ReturnType, char *Identifier);
|
struct ValueType *ReturnType, char *Identifier);
|
||||||
extern void ParseCleanup(Picoc *pc);
|
extern void ParseCleanup(Picoc *pc);
|
||||||
|
@ -578,11 +571,11 @@ extern int TypeSizeValue(struct Value *Val, int Compact);
|
||||||
extern int TypeStackSizeValue(struct Value *Val);
|
extern int TypeStackSizeValue(struct Value *Val);
|
||||||
extern int TypeLastAccessibleOffset(Picoc *pc, struct Value *Val);
|
extern int TypeLastAccessibleOffset(Picoc *pc, struct Value *Val);
|
||||||
extern int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
extern int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
int *IsStatic, int *IsExtern, int *IsVolatile);
|
int *IsStatic);
|
||||||
extern void TypeParseIdentPart(struct ParseState *Parser,
|
extern void TypeParseIdentPart(struct ParseState *Parser,
|
||||||
struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier);
|
struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier);
|
||||||
extern void TypeParse(struct ParseState *Parser, struct ValueType **Typ,
|
extern void TypeParse(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
char **Identifier, int *IsStatic, int *IsExtern, int *IsVolatile);
|
char **Identifier, int *IsStatic);
|
||||||
extern struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser,
|
extern struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser,
|
||||||
struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates);
|
struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates);
|
||||||
extern struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser,
|
extern struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser,
|
||||||
|
|
8
lex.c
8
lex.c
|
@ -93,11 +93,7 @@ static struct ReservedWord ReservedWords[] = {
|
||||||
{"union", TokenUnionType},
|
{"union", TokenUnionType},
|
||||||
{"unsigned", TokenUnsignedType},
|
{"unsigned", TokenUnsignedType},
|
||||||
{"void", TokenVoidType},
|
{"void", TokenVoidType},
|
||||||
{"while", TokenWhile},
|
{"while", TokenWhile}
|
||||||
{"volatile", TokenVolatileType},
|
|
||||||
{"#pragma", TokenHashPragma},
|
|
||||||
{"_Pragma", TokenUnderscorePragma},
|
|
||||||
{"const", TokenConstType}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -852,7 +848,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value,
|
||||||
#ifdef DEBUG_LEXER
|
#ifdef DEBUG_LEXER
|
||||||
printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos);
|
printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos);
|
||||||
#endif
|
#endif
|
||||||
assert(Token >= TokenNone && Token <= TokenConstType);
|
assert(Token >= TokenNone && Token <= TokenEndOfFunction);
|
||||||
return Token;
|
return Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
74
parse.c
74
parse.c
|
@ -1,7 +1,6 @@
|
||||||
/* picoc parser - parses source and executes statements */
|
/* picoc parser - parses source and executes statements */
|
||||||
#include "picoc.h"
|
#include "picoc.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "stats.h"
|
|
||||||
|
|
||||||
static enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser,
|
static enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser,
|
||||||
int Condition, int CheckTrailingSemicolon);
|
int Condition, int CheckTrailingSemicolon);
|
||||||
|
@ -12,7 +11,6 @@ static void ParseDeclarationAssignment(struct ParseState *Parser,
|
||||||
struct Value *NewVariable, int DoAssignment);
|
struct Value *NewVariable, int DoAssignment);
|
||||||
static int ParseDeclaration(struct ParseState *Parser, enum LexToken Token);
|
static int ParseDeclaration(struct ParseState *Parser, enum LexToken Token);
|
||||||
static void ParseMacroDefinition(struct ParseState *Parser);
|
static void ParseMacroDefinition(struct ParseState *Parser);
|
||||||
static void ParsePragma(struct ParseState *Parser);
|
|
||||||
static void ParseFor(struct ParseState *Parser);
|
static void ParseFor(struct ParseState *Parser);
|
||||||
static enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace,
|
static enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace,
|
||||||
int Condition);
|
int Condition);
|
||||||
|
@ -49,11 +47,11 @@ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser,
|
||||||
enum RunMode OldMode = Parser->Mode;
|
enum RunMode OldMode = Parser->Mode;
|
||||||
int Result;
|
int Result;
|
||||||
Parser->Mode = RunModeSkip;
|
Parser->Mode = RunModeSkip;
|
||||||
Result = ParseStatement(Parser, CheckTrailingSemicolon, false);
|
Result = ParseStatement(Parser, CheckTrailingSemicolon);
|
||||||
Parser->Mode = OldMode;
|
Parser->Mode = OldMode;
|
||||||
return (enum ParseResult)Result;
|
return (enum ParseResult)Result;
|
||||||
} else
|
} else
|
||||||
return ParseStatement(Parser, CheckTrailingSemicolon, false);
|
return ParseStatement(Parser, CheckTrailingSemicolon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count the number of parameters to a function or macro */
|
/* count the number of parameters to a function or macro */
|
||||||
|
@ -122,7 +120,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* add a parameter */
|
/* add a parameter */
|
||||||
TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL, NULL, NULL);
|
TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL);
|
||||||
if (ParamType->Base == TypeVoid) {
|
if (ParamType->Base == TypeVoid) {
|
||||||
/* this isn't a real parameter at all - delete it */
|
/* this isn't a real parameter at all - delete it */
|
||||||
//ParamCount--;
|
//ParamCount--;
|
||||||
|
@ -339,8 +337,6 @@ void ParseDeclarationAssignment(struct ParseState *Parser,
|
||||||
int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
||||||
{
|
{
|
||||||
int IsStatic = false;
|
int IsStatic = false;
|
||||||
int IsExtern = false;
|
|
||||||
int IsVolatile = false;
|
|
||||||
int FirstVisit = false;
|
int FirstVisit = false;
|
||||||
char *Identifier;
|
char *Identifier;
|
||||||
struct ValueType *BasicType;
|
struct ValueType *BasicType;
|
||||||
|
@ -348,7 +344,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
||||||
struct Value *NewVariable = NULL;
|
struct Value *NewVariable = NULL;
|
||||||
Picoc *pc = Parser->pc;
|
Picoc *pc = Parser->pc;
|
||||||
|
|
||||||
TypeParseFront(Parser, &BasicType, &IsStatic, &IsExtern, &IsVolatile);
|
TypeParseFront(Parser, &BasicType, &IsStatic);
|
||||||
do {
|
do {
|
||||||
TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier);
|
TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier);
|
||||||
if ((Token != TokenVoidType && Token != TokenStructType &&
|
if ((Token != TokenVoidType && Token != TokenStructType &&
|
||||||
|
@ -362,8 +358,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
||||||
{
|
{
|
||||||
ParseFunctionDefinition(Parser, Typ, Identifier);
|
ParseFunctionDefinition(Parser, Typ, Identifier);
|
||||||
return false;
|
return false;
|
||||||
} else if (!IsExtern) {
|
} else {
|
||||||
/* extern means declaration rather than definition, so ignore */
|
|
||||||
if (Typ == &pc->VoidType && Identifier != pc->StrEmpty)
|
if (Typ == &pc->VoidType && Identifier != pc->StrEmpty)
|
||||||
ProgramFail(Parser, "can't define a void variable");
|
ProgramFail(Parser, "can't define a void variable");
|
||||||
|
|
||||||
|
@ -454,14 +449,6 @@ void ParseMacroDefinition(struct ParseState *Parser)
|
||||||
ProgramFail(Parser, "'%s' is already defined", MacroNameStr);
|
ProgramFail(Parser, "'%s' is already defined", MacroNameStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse a pragma */
|
|
||||||
void ParsePragma(struct ParseState *Parser)
|
|
||||||
{
|
|
||||||
/* consume tokens until we hit the end of a line */
|
|
||||||
/* (not ideal for _Pragma() but it'll do for now) */
|
|
||||||
LexToEndOfMacro(Parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the entire parser state */
|
/* copy the entire parser state */
|
||||||
void ParserCopy(struct ParseState *To, struct ParseState *From)
|
void ParserCopy(struct ParseState *To, struct ParseState *From)
|
||||||
{
|
{
|
||||||
|
@ -495,18 +482,8 @@ void ParseFor(struct ParseState *Parser)
|
||||||
if (LexGetToken(Parser, NULL, true) != TokenOpenBracket)
|
if (LexGetToken(Parser, NULL, true) != TokenOpenBracket)
|
||||||
ProgramFail(Parser, "'(' expected");
|
ProgramFail(Parser, "'(' expected");
|
||||||
|
|
||||||
if (LexGetToken(Parser, NULL, false) != TokenSemicolon) {
|
if (ParseStatement(Parser, true) != ParseResultOk)
|
||||||
if (ParseStatement(Parser, false, true) != ParseResultOk)
|
ProgramFail(Parser, "statement expected");
|
||||||
ProgramFail(Parser, "statement expected");
|
|
||||||
while (LexGetToken(Parser, NULL, false) == TokenComma) {
|
|
||||||
LexGetToken(Parser, NULL, true);
|
|
||||||
if (ParseStatement(Parser, false, true) != ParseResultOk)
|
|
||||||
ProgramFail(Parser, "statement expected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LexGetToken(Parser, NULL, true) != TokenSemicolon)
|
|
||||||
ProgramFail(Parser, "';' expected");
|
|
||||||
|
|
||||||
ParserCopyPos(&PreConditional, Parser);
|
ParserCopyPos(&PreConditional, Parser);
|
||||||
if (LexGetToken(Parser, NULL, false) == TokenSemicolon)
|
if (LexGetToken(Parser, NULL, false) == TokenSemicolon)
|
||||||
|
@ -519,10 +496,6 @@ void ParseFor(struct ParseState *Parser)
|
||||||
|
|
||||||
ParserCopyPos(&PreIncrement, Parser);
|
ParserCopyPos(&PreIncrement, Parser);
|
||||||
ParseStatementMaybeRun(Parser, false, false);
|
ParseStatementMaybeRun(Parser, false, false);
|
||||||
while (LexGetToken(Parser, NULL, false) == TokenComma) {
|
|
||||||
LexGetToken(Parser, NULL, true);
|
|
||||||
ParseStatementMaybeRun(Parser, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LexGetToken(Parser, NULL, true) != TokenCloseBracket)
|
if (LexGetToken(Parser, NULL, true) != TokenCloseBracket)
|
||||||
ProgramFail(Parser, "')' expected");
|
ProgramFail(Parser, "')' expected");
|
||||||
|
@ -538,11 +511,7 @@ void ParseFor(struct ParseState *Parser)
|
||||||
|
|
||||||
while (Condition && Parser->Mode == RunModeRun) {
|
while (Condition && Parser->Mode == RunModeRun) {
|
||||||
ParserCopyPos(Parser, &PreIncrement);
|
ParserCopyPos(Parser, &PreIncrement);
|
||||||
ParseStatement(Parser, false, false);
|
ParseStatement(Parser, false);
|
||||||
while (LexGetToken(Parser, NULL, false) == TokenComma) {
|
|
||||||
LexGetToken(Parser, NULL, true);
|
|
||||||
ParseStatement(Parser, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParserCopyPos(Parser, &PreConditional);
|
ParserCopyPos(Parser, &PreConditional);
|
||||||
if (LexGetToken(Parser, NULL, false) == TokenSemicolon)
|
if (LexGetToken(Parser, NULL, false) == TokenSemicolon)
|
||||||
|
@ -552,7 +521,7 @@ void ParseFor(struct ParseState *Parser)
|
||||||
|
|
||||||
if (Condition) {
|
if (Condition) {
|
||||||
ParserCopyPos(Parser, &PreStatement);
|
ParserCopyPos(Parser, &PreStatement);
|
||||||
ParseStatement(Parser, true, false);
|
ParseStatement(Parser, true);
|
||||||
|
|
||||||
if (Parser->Mode == RunModeContinue)
|
if (Parser->Mode == RunModeContinue)
|
||||||
Parser->Mode = RunModeRun;
|
Parser->Mode = RunModeRun;
|
||||||
|
@ -581,12 +550,12 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace,
|
||||||
/* condition failed - skip this block instead */
|
/* condition failed - skip this block instead */
|
||||||
enum RunMode OldMode = Parser->Mode;
|
enum RunMode OldMode = Parser->Mode;
|
||||||
Parser->Mode = RunModeSkip;
|
Parser->Mode = RunModeSkip;
|
||||||
while (ParseStatement(Parser, true, false) == ParseResultOk) {
|
while (ParseStatement(Parser, true) == ParseResultOk) {
|
||||||
}
|
}
|
||||||
Parser->Mode = OldMode;
|
Parser->Mode = OldMode;
|
||||||
} else {
|
} else {
|
||||||
/* just run it in its current mode */
|
/* just run it in its current mode */
|
||||||
while (ParseStatement(Parser, true, false) == ParseResultOk) {
|
while (ParseStatement(Parser, true) == ParseResultOk) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +575,7 @@ void ParseTypedef(struct ParseState *Parser)
|
||||||
struct ValueType **TypPtr;
|
struct ValueType **TypPtr;
|
||||||
struct Value InitValue;
|
struct Value InitValue;
|
||||||
|
|
||||||
TypeParse(Parser, &Typ, &TypeName, NULL, NULL, NULL);
|
TypeParse(Parser, &Typ, &TypeName, NULL);
|
||||||
|
|
||||||
if (Parser->Mode == RunModeRun) {
|
if (Parser->Mode == RunModeRun) {
|
||||||
TypPtr = &Typ;
|
TypPtr = &Typ;
|
||||||
|
@ -618,7 +587,7 @@ void ParseTypedef(struct ParseState *Parser)
|
||||||
|
|
||||||
/* parse a statement */
|
/* parse a statement */
|
||||||
enum ParseResult ParseStatement(struct ParseState *Parser,
|
enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
int CheckTrailingSemicolon, int DoNotConsumeTrailingSemicolon)
|
int CheckTrailingSemicolon)
|
||||||
{
|
{
|
||||||
int Condition;
|
int Condition;
|
||||||
enum LexToken Token;
|
enum LexToken Token;
|
||||||
|
@ -638,8 +607,6 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
ParserCopy(&PreState, Parser);
|
ParserCopy(&PreState, Parser);
|
||||||
Token = LexGetToken(Parser, &LexerValue, true);
|
Token = LexGetToken(Parser, &LexerValue, true);
|
||||||
|
|
||||||
stats_log_statement(Token, Parser);
|
|
||||||
|
|
||||||
switch (Token) {
|
switch (Token) {
|
||||||
case TokenEOF:
|
case TokenEOF:
|
||||||
return ParseResultEOF;
|
return ParseResultEOF;
|
||||||
|
@ -728,7 +695,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
ParserCopyPos(&PreStatement, Parser);
|
ParserCopyPos(&PreStatement, Parser);
|
||||||
do {
|
do {
|
||||||
ParserCopyPos(Parser, &PreStatement);
|
ParserCopyPos(Parser, &PreStatement);
|
||||||
if (ParseStatement(Parser, true, false) != ParseResultOk)
|
if (ParseStatement(Parser, true) != ParseResultOk)
|
||||||
ProgramFail(Parser, "statement expected");
|
ProgramFail(Parser, "statement expected");
|
||||||
if (Parser->Mode == RunModeContinue)
|
if (Parser->Mode == RunModeContinue)
|
||||||
Parser->Mode = PreMode;
|
Parser->Mode = PreMode;
|
||||||
|
@ -767,8 +734,6 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
case TokenAutoType:
|
case TokenAutoType:
|
||||||
case TokenRegisterType:
|
case TokenRegisterType:
|
||||||
case TokenExternType:
|
case TokenExternType:
|
||||||
case TokenVolatileType:
|
|
||||||
case TokenConstType:
|
|
||||||
*Parser = PreState;
|
*Parser = PreState;
|
||||||
CheckTrailingSemicolon = ParseDeclaration(Parser, Token);
|
CheckTrailingSemicolon = ParseDeclaration(Parser, Token);
|
||||||
break;
|
break;
|
||||||
|
@ -883,18 +848,13 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TokenHashPragma:
|
|
||||||
case TokenUnderscorePragma:
|
|
||||||
ParsePragma(Parser);
|
|
||||||
CheckTrailingSemicolon = false;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
*Parser = PreState;
|
*Parser = PreState;
|
||||||
return ParseResultError;
|
return ParseResultError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckTrailingSemicolon) {
|
if (CheckTrailingSemicolon) {
|
||||||
if (LexGetToken(Parser, NULL, !DoNotConsumeTrailingSemicolon) != TokenSemicolon)
|
if (LexGetToken(Parser, NULL, true) != TokenSemicolon)
|
||||||
ProgramFail(Parser, "';' expected");
|
ProgramFail(Parser, "';' expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -934,7 +894,7 @@ void PicocParse(Picoc *pc, const char *FileName, const char *Source,
|
||||||
EnableDebugger);
|
EnableDebugger);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
Ok = ParseStatement(&Parser, true, false);
|
Ok = ParseStatement(&Parser, true);
|
||||||
} while (Ok == ParseResultOk);
|
} while (Ok == ParseResultOk);
|
||||||
|
|
||||||
if (Ok == ParseResultError)
|
if (Ok == ParseResultError)
|
||||||
|
@ -957,7 +917,7 @@ void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
LexInteractiveStatementPrompt(pc);
|
LexInteractiveStatementPrompt(pc);
|
||||||
Ok = ParseStatement(&Parser, true, false);
|
Ok = ParseStatement(&Parser, true);
|
||||||
LexInteractiveCompleted(pc, &Parser);
|
LexInteractiveCompleted(pc, &Parser);
|
||||||
|
|
||||||
} while (Ok == ParseResultOk);
|
} while (Ok == ParseResultOk);
|
||||||
|
|
28
picoc.c
28
picoc.c
|
@ -10,33 +10,29 @@
|
||||||
/* include only picoc.h here - should be able to use it with only the
|
/* include only picoc.h here - should be able to use it with only the
|
||||||
external interfaces, no internals from interpreter.h */
|
external interfaces, no internals from interpreter.h */
|
||||||
#include "picoc.h"
|
#include "picoc.h"
|
||||||
#include "stats.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(UNIX_HOST) || defined(WIN32)
|
#if defined(UNIX_HOST) || defined(WIN32)
|
||||||
#include "LICENSE.h"
|
#include "LICENSE.h"
|
||||||
|
|
||||||
/* Override via STACKSIZE environment variable */
|
/* Override via STACKSIZE environment variable */
|
||||||
#define PICOC_STACK_SIZE (32*1024*1024)
|
#define PICOC_STACK_SIZE (128000*4)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ParamCount = 1;
|
int ParamCount = 1;
|
||||||
int DontRunMain = false;
|
int DontRunMain = false;
|
||||||
int CollectStats = false;
|
|
||||||
int StatsType = 0;
|
|
||||||
int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE;
|
int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE;
|
||||||
Picoc pc;
|
Picoc pc;
|
||||||
|
|
||||||
if (argc < 2 || strcmp(argv[ParamCount], "-h") == 0) {
|
if (argc < 2 || strcmp(argv[ParamCount], "-h") == 0) {
|
||||||
printf(PICOC_VERSION " \n"
|
printf(PICOC_VERSION " \n"
|
||||||
"Format:\n\n"
|
"Format:\n\n"
|
||||||
"> picoc <file1.c>... [- <arg1>...] : run a program, calls main() as the entry point\n"
|
"> picoc <file1.c>... [- <arg1>...] : run a program, calls main() as the entry point\n"
|
||||||
"> picoc -s <file1.c>... [- <arg1>...] : run a script, runs the program without calling main()\n"
|
"> picoc -s <file1.c>... [- <arg1>...] : run a script, runs the program without calling main()\n"
|
||||||
"> picoc -d[type] <file1.c>... [- <arg1>...] : run a program, outputting debugging stats\n"
|
"> picoc -i : interactive mode, Ctrl+d to exit\n"
|
||||||
"> picoc -i : interactive mode, Ctrl+d to exit\n"
|
"> picoc -c : copyright info\n"
|
||||||
"> picoc -c : copyright info\n"
|
"> picoc -h : this help message\n");
|
||||||
"> picoc -h : this help message\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +47,6 @@ int main(int argc, char **argv)
|
||||||
DontRunMain = true;
|
DontRunMain = true;
|
||||||
PicocIncludeAllSystemHeaders(&pc);
|
PicocIncludeAllSystemHeaders(&pc);
|
||||||
ParamCount++;
|
ParamCount++;
|
||||||
} else if (strncmp(argv[ParamCount], "-d", 2) == 0) {
|
|
||||||
if (strlen(argv[ParamCount]) > 2) {
|
|
||||||
StatsType = atoi(&argv[ParamCount][2]);
|
|
||||||
}
|
|
||||||
CollectStats = true;
|
|
||||||
pc.CollectStats = true;
|
|
||||||
ParamCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) {
|
if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) {
|
||||||
|
@ -77,11 +66,6 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
PicocCleanup(&pc);
|
PicocCleanup(&pc);
|
||||||
|
|
||||||
if (CollectStats) {
|
|
||||||
stats_print_tokens(StatsType == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pc.PicocExitValue;
|
return pc.PicocExitValue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
#define STRING_TABLE_SIZE (97) /* shared string table size */
|
#define STRING_TABLE_SIZE (97) /* shared string table size */
|
||||||
#define STRING_LITERAL_TABLE_SIZE (97) /* string literal table size */
|
#define STRING_LITERAL_TABLE_SIZE (97) /* string literal table size */
|
||||||
#define RESERVED_WORD_TABLE_SIZE (97) /* reserved word table size */
|
#define RESERVED_WORD_TABLE_SIZE (97) /* reserved word table size */
|
||||||
#define PARAMETER_MAX (32) /* maximum number of parameters to a function */
|
#define PARAMETER_MAX (16) /* maximum number of parameters to a function */
|
||||||
#define LINEBUFFER_MAX (256) /* maximum number of characters on a line */
|
#define LINEBUFFER_MAX (256) /* maximum number of characters on a line */
|
||||||
#define LOCAL_TABLE_SIZE (11) /* size of local variable table (can expand) */
|
#define LOCAL_TABLE_SIZE (11) /* size of local variable table (can expand) */
|
||||||
#define STRUCT_TABLE_SIZE (11) /* size of struct/union member table (can expand) */
|
#define STRUCT_TABLE_SIZE (11) /* size of struct/union member table (can expand) */
|
||||||
|
|
153
stats.c
153
stats.c
|
@ -1,153 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Russell Joyce on 12/05/2020.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "stats.h"
|
|
||||||
|
|
||||||
const char *RunModeNames[NO_RUN_MODES] = {
|
|
||||||
"RunModeRun",
|
|
||||||
"RunModeSkip",
|
|
||||||
"RunModeReturn",
|
|
||||||
"RunModeCaseSearch",
|
|
||||||
"RunModeBreak",
|
|
||||||
"RunModeContinue",
|
|
||||||
"RunModeGoto"
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LexTokenStat LexTokenStats[NO_TOKENS] = {
|
|
||||||
{"TokenNone", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenComma", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenAddAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSubtractAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenMultiplyAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDivideAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenModulusAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenShiftLeftAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenShiftRightAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArithmeticAndAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArithmeticOrAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArithmeticExorAssign", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenQuestionMark", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenColon", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLogicalOr", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLogicalAnd", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArithmeticOr", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArithmeticExor", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenAmpersand", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEqual", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenNotEqual", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLessThan", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenGreaterThan", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLessEqual", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenGreaterEqual", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenShiftLeft", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenShiftRight", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenPlus", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenMinus", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenAsterisk", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSlash", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenModulus", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenIncrement", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDecrement", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenUnaryNot", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenUnaryExor", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSizeof", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenCast", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLeftSquareBracket", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenRightSquareBracket", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDot", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenArrow", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenOpenBracket", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenCloseBracket", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenIdentifier", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenIntegerConstant", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenFPConstant", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenStringConstant", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenCharacterConstant", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSemicolon", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEllipsis", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLeftBrace", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenRightBrace", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenIntType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenCharType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenFloatType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDoubleType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenVoidType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEnumType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenLongType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSignedType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenShortType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenStaticType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenAutoType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenRegisterType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenExternType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenStructType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenUnionType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenUnsignedType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenTypedef", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenContinue", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDo", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenElse", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenFor", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenGoto", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenIf", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenWhile", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenBreak", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenSwitch", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenCase", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDefault", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenReturn", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashDefine", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashInclude", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashIf", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashIfdef", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashIfndef", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashElse", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashEndif", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenNew", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenDelete", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenOpenMacroBracket", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEOF", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEndOfLine", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenEndOfFunction", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenBackSlash", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenVolatileType", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenHashPragma", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenUnderscorePragma", {0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{"TokenConstType", {0, 0, 0, 0, 0, 0, 0}}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void stats_log_statement(enum LexToken token, struct ParseState *parser) {
|
|
||||||
if (parser->pc->CollectStats) {
|
|
||||||
fprintf(stderr, "Parsing Statement %s (%d) in %s (%d) at %s:%d:%d\n", LexTokenStats[token].name, token,
|
|
||||||
RunModeNames[parser->Mode], parser->Mode, parser->FileName, parser->Line, parser->CharacterPos);
|
|
||||||
LexTokenStats[token].count[parser->Mode]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void stats_log_expression(enum LexToken token, struct ParseState *parser) {
|
|
||||||
if (parser->pc->CollectStats) {
|
|
||||||
fprintf(stderr, "Parsing Expression %s (%d) in %s (%d) at %s:%d:%d\n", LexTokenStats[token].name, token,
|
|
||||||
RunModeNames[parser->Mode], parser->Mode, parser->FileName, parser->Line, parser->CharacterPos);
|
|
||||||
LexTokenStats[token].count[parser->Mode]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void stats_print_tokens(int all) {
|
|
||||||
fprintf(stderr, "\n*********\nToken stats:\n");
|
|
||||||
for (int i = 0; i < NO_RUN_MODES; i++) {
|
|
||||||
fprintf(stderr, "***\n");
|
|
||||||
fprintf(stderr, "%s\n", RunModeNames[i]);
|
|
||||||
for (int j = 0; j < NO_TOKENS; j++) {
|
|
||||||
if (all || LexTokenStats[j].count[i] > 0) {
|
|
||||||
fprintf(stderr, "%5d %s\n", LexTokenStats[j].count[i],
|
|
||||||
LexTokenStats[j].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "*********\n");
|
|
||||||
}
|
|
26
stats.h
26
stats.h
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Russell Joyce on 12/05/2020.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef PICOC_STATS_H
|
|
||||||
#define PICOC_STATS_H
|
|
||||||
|
|
||||||
#include "interpreter.h"
|
|
||||||
|
|
||||||
#define NO_RUN_MODES 7
|
|
||||||
#define NO_TOKENS 101
|
|
||||||
|
|
||||||
extern const char *RunModeNames[NO_RUN_MODES];
|
|
||||||
|
|
||||||
struct LexTokenStat {
|
|
||||||
const char* name;
|
|
||||||
int count[NO_RUN_MODES];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct LexTokenStat LexTokenStats[NO_TOKENS];
|
|
||||||
|
|
||||||
void stats_log_statement(enum LexToken token, struct ParseState *parser);
|
|
||||||
void stats_log_expression(enum LexToken token, struct ParseState *parser);
|
|
||||||
void stats_print_tokens(int all);
|
|
||||||
|
|
||||||
#endif //PICOC_STATS_H
|
|
52
type.c
52
type.c
|
@ -265,7 +265,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
STRUCT_TABLE_SIZE, true);
|
STRUCT_TABLE_SIZE, true);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
TypeParse(Parser, &MemberType, &MemberIdentifier, NULL, NULL, NULL);
|
TypeParse(Parser, &MemberType, &MemberIdentifier, NULL);
|
||||||
if (MemberType == NULL || MemberIdentifier == NULL)
|
if (MemberType == NULL || MemberIdentifier == NULL)
|
||||||
ProgramFail(Parser, "invalid type in struct");
|
ProgramFail(Parser, "invalid type in struct");
|
||||||
|
|
||||||
|
@ -393,12 +393,10 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
|
||||||
|
|
||||||
/* parse a type - just the basic type */
|
/* parse a type - just the basic type */
|
||||||
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
int *IsStatic, int *IsExtern, int *IsVolatile)
|
int *IsStatic)
|
||||||
{
|
{
|
||||||
int Unsigned = false;
|
int Unsigned = false;
|
||||||
int StaticQualifier = false;
|
int StaticQualifier = false;
|
||||||
int ExternQualifier = false;
|
|
||||||
int VolatileQualifier = false;
|
|
||||||
enum LexToken Token;
|
enum LexToken Token;
|
||||||
struct ParseState Before;
|
struct ParseState Before;
|
||||||
struct Value *LexerValue;
|
struct Value *LexerValue;
|
||||||
|
@ -406,49 +404,23 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
Picoc *pc = Parser->pc;
|
Picoc *pc = Parser->pc;
|
||||||
*Typ = NULL;
|
*Typ = NULL;
|
||||||
|
|
||||||
|
/* ignore leading type qualifiers */
|
||||||
ParserCopy(&Before, Parser);
|
ParserCopy(&Before, Parser);
|
||||||
Token = LexGetToken(Parser, &LexerValue, true);
|
Token = LexGetToken(Parser, &LexerValue, true);
|
||||||
|
|
||||||
/* handle any leading type qualifiers/storage classes */
|
|
||||||
while (Token == TokenStaticType || Token == TokenAutoType ||
|
while (Token == TokenStaticType || Token == TokenAutoType ||
|
||||||
Token == TokenRegisterType || Token == TokenExternType ||
|
Token == TokenRegisterType || Token == TokenExternType) {
|
||||||
Token == TokenVolatileType || Token == TokenConstType) {
|
|
||||||
if (Token == TokenStaticType)
|
if (Token == TokenStaticType)
|
||||||
StaticQualifier = true;
|
StaticQualifier = true;
|
||||||
else if (Token == TokenExternType)
|
|
||||||
ExternQualifier = true;
|
|
||||||
else if (Token == TokenVolatileType)
|
|
||||||
VolatileQualifier = true;
|
|
||||||
|
|
||||||
Token = LexGetToken(Parser, &LexerValue, true);
|
Token = LexGetToken(Parser, &LexerValue, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle any trailing type qualifiers/storage classes */
|
|
||||||
enum LexToken FollowToken = LexGetToken(Parser, NULL, false);
|
|
||||||
while (FollowToken == TokenStaticType || FollowToken == TokenAutoType ||
|
|
||||||
FollowToken == TokenRegisterType || FollowToken == TokenExternType ||
|
|
||||||
FollowToken == TokenVolatileType || FollowToken == TokenConstType) {
|
|
||||||
if (FollowToken == TokenStaticType)
|
|
||||||
StaticQualifier = true;
|
|
||||||
else if (FollowToken == TokenExternType)
|
|
||||||
ExternQualifier = true;
|
|
||||||
else if (FollowToken == TokenVolatileType)
|
|
||||||
VolatileQualifier = true;
|
|
||||||
|
|
||||||
LexGetToken(Parser, NULL, true);
|
|
||||||
FollowToken = LexGetToken(Parser, NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsStatic != NULL)
|
if (IsStatic != NULL)
|
||||||
*IsStatic = StaticQualifier;
|
*IsStatic = StaticQualifier;
|
||||||
if (IsExtern != NULL)
|
|
||||||
*IsExtern = ExternQualifier;
|
|
||||||
if (IsVolatile != NULL)
|
|
||||||
*IsVolatile = VolatileQualifier;
|
|
||||||
|
|
||||||
/* handle signed/unsigned with no trailing type */
|
/* handle signed/unsigned with no trailing type */
|
||||||
if (Token == TokenSignedType || Token == TokenUnsignedType) {
|
if (Token == TokenSignedType || Token == TokenUnsignedType) {
|
||||||
enum LexToken FollowToken = LexGetToken(Parser, NULL, false);
|
enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, false);
|
||||||
Unsigned = (Token == TokenUnsignedType);
|
Unsigned = (Token == TokenUnsignedType);
|
||||||
|
|
||||||
if (FollowToken != TokenIntType && FollowToken != TokenLongType &&
|
if (FollowToken != TokenIntType && FollowToken != TokenLongType &&
|
||||||
|
@ -464,14 +436,6 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
Token = LexGetToken(Parser, &LexerValue, true);
|
Token = LexGetToken(Parser, &LexerValue, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle long or short with trailing int by consuming and ignoring the int */
|
|
||||||
if (Token == TokenLongType || Token == TokenShortType) {
|
|
||||||
enum LexToken FollowToken = LexGetToken(Parser, NULL, false);
|
|
||||||
if (FollowToken == TokenIntType) {
|
|
||||||
LexGetToken(Parser, NULL, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Token) {
|
switch (Token) {
|
||||||
case TokenIntType:
|
case TokenIntType:
|
||||||
*Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType;
|
*Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType;
|
||||||
|
@ -577,7 +541,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp,
|
||||||
if (*Typ != NULL)
|
if (*Typ != NULL)
|
||||||
ProgramFail(Parser, "bad type declaration");
|
ProgramFail(Parser, "bad type declaration");
|
||||||
|
|
||||||
TypeParse(Parser, Typ, Identifier, NULL, NULL, NULL);
|
TypeParse(Parser, Typ, Identifier, NULL);
|
||||||
if (LexGetToken(Parser, NULL, true) != TokenCloseBracket)
|
if (LexGetToken(Parser, NULL, true) != TokenCloseBracket)
|
||||||
ProgramFail(Parser, "')' expected");
|
ProgramFail(Parser, "')' expected");
|
||||||
break;
|
break;
|
||||||
|
@ -613,11 +577,11 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp,
|
||||||
|
|
||||||
/* parse a type - a complete declaration including identifier */
|
/* parse a type - a complete declaration including identifier */
|
||||||
void TypeParse(struct ParseState *Parser, struct ValueType **Typ,
|
void TypeParse(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
char **Identifier, int *IsStatic, int *IsExtern, int *IsVolatile)
|
char **Identifier, int *IsStatic)
|
||||||
{
|
{
|
||||||
struct ValueType *BasicType;
|
struct ValueType *BasicType;
|
||||||
|
|
||||||
TypeParseFront(Parser, &BasicType, IsStatic, IsExtern, IsVolatile);
|
TypeParseFront(Parser, &BasicType, IsStatic);
|
||||||
TypeParseIdentPart(Parser, BasicType, Typ, Identifier);
|
TypeParseIdentPart(Parser, BasicType, Typ, Identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
/* maximum size of a value to temporarily copy while we create a variable */
|
/* maximum size of a value to temporarily copy while we create a variable */
|
||||||
#define MAX_TMP_COPY_BUF (2048)
|
#define MAX_TMP_COPY_BUF (256)
|
||||||
|
|
||||||
|
|
||||||
/* initialize the variable system */
|
/* initialize the variable system */
|
||||||
|
|
Loading…
Reference in a new issue